3

I have this component:

import {Component} from 'angular2/core';
import {UserServices} from '../services/UserServices';

@Component({
    selector: 'users',
    template: '<h1>HOLA</h1>'
})

export class UsersComponent {
    users: Object;

    constructor(userServices: UserServices) {
        userServices.getUsersList();
    }
}

And In the UserServices I have this code:

import {Http} from 'angular2/http'

export class UserServices {
    users: Array<any>;
    http: any;

    constructor(http: Http) {
        this.http = http;
    }

    getUsersList() {
        this.http.get('./users.json').map((res: Response) => res.json()).subscribe(res => console.log(res));
    }

}

I want to call an ajax call for the users custom tag. But I'm getting this error:

Cannot resolve all parameters for UserServices(?). Make sure they all have valid type or annotations.

When I remove the HTTP parameters, import and call, it has no error, so I guess the problem is there, but I cannot find out the problem

2 Answers 2

6

You are missing couple of relevant sections in DI.

There are multiple ways to inject using provide and @inject or using @Injectable decorators. Here you, for instance, decorate your service with @Injectable i.e

import {Injectable} from 'angular2/core';
import {Http, Response} from 'angular2/http';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/map';

// You do not need to do this, but creating an interface for more strong typing. You could as well create a User class here and use that as view model.
interface IUser{
  name:string;
}

@Injectable()
class UserServices {
    users: Array<IUser>;

    constructor(private http:Http) {}

    getUsersList():Observable<Array<IUser>> {
       return this.http.get('./users.json')
            .map((res: Response) => res.json());
    }

}

export {IUser, UserServices};

Inject UserServices and HTTP_PROVIDERS at the root, Generally you inject the services that you need as singleton across your app at the app root level. If not, you can inject the service alone in the UserComponent decorator's providers array.

i.e

bootstrap(UsersComponent, [HTTP_PROVIDERS, UserServices])

or within the component's decorator:

@Component({
    selector: 'users',
    template: `<h1>Users</h1>
    <div *ngFor="#user of users">
    {{user.name}}
    </div>

    `,
    providers:[UserServices] 
})

Consume this in your component and subscribe 1 to the returned observable.

export class UsersComponent {
    users: Array<IUser>;

    constructor(userServices: UserServices) {
        userServices.getUsersList().subscribe(users => this.users = users);
    }
}

1You can also use async pipe (application of this depends upon the use case) and set the value of this.users as the observable instead of subscribing them explicitly.

<div *ngFor="#user of users | async">
  {{user.name}}
</div>

and

this.users = userServices.getUsersList();

Note: In the example i just imported map operator in order to get the map as a part of observable returned by http (import rxjs/add/operator/map) since this is not mapped in the system Js config paths property at a global level.

Here is a working plunker Demo.

Sign up to request clarification or add additional context in comments.

3 Comments

Perfect!! Thankss a lot!
@PSL I have a question not regarding the subject if you don't mind. What the heck is <> you use multiple times? I mean why you use Array<IUser> and not IUser[]? How is it called, and where I can learn more about it?
@Eggy sure, it is part of generics syntax to specify the sub type of a generic type like Observable, Array, promise etc or any other custom types as well. But to you point in case if array you could use the literal syntax as well i.e []. More about generics here typescriptlang.org/Handbook#generics . Hope this helps.
2

The service needs an Injectable() annotation

import {Injectable} from 'angular2/core';

@Injectable()
export class UsersComponent {

for DI to be able to inject Http or other dependencies to its constructor.

7 Comments

You're missing the @ :P
yes yes. It will sound strange, but after adding that lines I'm getting SyntaxError: expected expression, got '<' o.O
I don't have a solution for this. Seems unrelated.
what's the content of users.json?, make sure it's all json correct syntax, no js comments or anything else.
When I add the http: Http to the constructor, I have the issue
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.