Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting an object array from an Angular service

Tags:

I am new to Angular (and Javascript for that matter). I've written an Angular service which returns an array of users. The data is retrieved from an HTTP call which returns the data in JSON format. When logging the JSON data returned from the HTTP call, I can see that this call is successful and the correct data is returned. I have a component which calls the service to get the users and an HTML page which displays the users. I cannot get the data from the service to the component. I suspect I am using the Observable incorrectly. Maybe I'm using subscribe incorrectly as well. If I comment out the getUsers call in the ngInit function and uncomment the getUsersMock call, everything works fine and I see the data displayed in the listbox in the HTML page. I'd like to convert the JSON data to an array or list of Users in the service, rather then returning JSON from the service and having the component convert it.

Data returned from HTTP call to get users:

[     {         "firstName": "Jane",         "lastName": "Doe"     },     {         "firstName": "John",         "lastName": "Doe"     } ] 

user.ts

export class User {     firstName: string;     lastName: string; } 

user-service.ts

... @Injectable export class UserService {     private USERS: User[] = [         {             firstName: 'Jane',             lastName: 'Doe'         },         {             firstName: 'John',             lastName: 'Doe'         }     ];      constructor (private http: Http) {}      getUsersMock(): User[] {         return this.USERS;     }      getUsers(): Observable<User[]> {         return Observable.create(observer => {             this.http.get('http://users.org').map(response => response.json();         })     } ... 

user.component.ts

... export class UserComponent implements OnInit {     users: User[] = {};      constructor(private userService: UserService) {}      ngOnInit(): void {         this.getUsers();         //this.getUsersMock();     }      getUsers(): void {         var userObservable = this.userService.getUsers();         this.userObservable.subscribe(users => { this.users = users });     }      getUsersMock(): void {         this.users = this.userService.getUsersMock();     } } ... 

user.component.html

... <select disabled="disabled" name="Users" size="20">     <option *ngFor="let user of users">         {{user.firstName}}, {{user.lastName}}     </option> </select> ... 

!!! UPDATE !!!

I had been reading the "heroes" tutorial, but wasn't working for me so I went off and tried other things. I've re-implemented my code the way the heroes tutorial describes. However, when I log the value of this.users, it reports undefined.

Here is my revised user-service.ts

... @Injectable export class UserService {     private USERS: User[] = [         {             firstName: 'Jane',             lastName: 'Doe'         },         {             firstName: 'John',             lastName: 'Doe'         }     ];      constructor (private http: Http) {}      getUsersMock(): User[] {         return this.USERS;     }      getUsers(): Promise<User[]> {         return this.http.get('http://users.org')             .toPromise()             .then(response => response.json().data as User[])             .catch(this.handleError);     } ... 

Here is my revised user.component.ts

... export class UserComponent implements OnInit {     users: User[] = {};      constructor(private userService: UserService) {}      ngOnInit(): void {         this.getUsers();         //this.getUsersMock();     }      getUsers(): void {         this.userService.getUsers()             .then(users => this.users = users);          console.log('this.users=' + this.users); // logs undefined     }      getUsersMock(): void {         this.users = this.userService.getUsersMock();     } } ... 

!!!!!!!!!! FINAL WORKING SOLUTION !!!!!!!!!! This is all the files for the final working solution:

user.ts

export class User {     public firstName: string; } 

user.service.ts

import { Injectable }     from '@angular/core'; import { Http, Response } from '@angular/http'; import { Observable }     from 'rxjs/Observable';  import 'rxjs/add/operator/catch'; import 'rxjs/add/operator/map';  import { User } from './user';  @Injectable() export class UserService {     // Returns this JSON data:     // [{"firstName":"Jane"},{"firstName":"John"}]     private URL = 'http://users.org';      constructor (private http: Http) {}      getUsers(): Observable<User[]> {         return this.http.get(this.URL)             .map((response:Response) => response.json())                 .catch((error:any) => Observable.throw(error.json().error || 'Server error'));     } } 

user.component.ts

import { Component, OnInit }   from '@angular/core'; import { Router }              from '@angular/router';  import { User }        from './user'; import { UserService } from './user.service';   @Component({     moduleId: module.id,     selector: 'users-list',     template:  `         <select size="5">             <option *ngFor="let user of users">{{user.firstName}}</option>         </select>     ` })  export class UserComponent implements OnInit{     users: User[];     title = 'List Users';      constructor(private userService: UserService) {}      getUsers(): void {         this.userService.getUsers()             .subscribe(                 users => {                     this.users = users;                     console.log('this.users=' + this.users);                     console.log('this.users.length=' + this.users.length);                     console.log('this.users[0].firstName=' + this.users[0].firstName);                 }, //Bind to view                             err => {                         // Log errors if any                         console.log(err);                     })     }      ngOnInit(): void {         this.getUsers();     } } 
like image 778
Nho Jotom Avatar asked Oct 26 '16 07:10

Nho Jotom


People also ask

What is an array of objects in angular?

Array of objects is populated and displayed to Dropdown or radio button display. Declare and initialize array using any / object type declared as follows Objects are properties which contains key and values, There is no type to represent object in Typescript and angular In typescript, Object can be declared using any type

What does it attach to the view in AngularJS?

It attaches a AngularJS controller to the view. Above is the example to create an single object and accessing the object in AngularJs. Creating array of Objects :

What is an angular service?

An Angular service is simply a function that allows you to access its properties and methods. For example, if we have any code which gets the data we will use it in one component and now if you want to use the same code in another component to get the same data , we will not add the same code again and again.

How to represent an object in AngularJS?

Above is the example snippet to represent an object in AngularJs. Here Student is an object and sId, sName, sAddress and marks are the properties of student object. $scope is an object of AngularJs, which refers to the application’s model. Bind the student details with view. ng-controller directive is used to bind the view with Angular controller.


1 Answers

Take a look at your code :

 getUsers(): Observable<User[]> {         return Observable.create(observer => {             this.http.get('http://users.org').map(response => response.json();         })     } 

and code from https://angular.io/docs/ts/latest/tutorial/toh-pt6.html (BTW. really good tutorial, you should check it out)

 getHeroes(): Promise<Hero[]> {     return this.http.get(this.heroesUrl)                .toPromise()                .then(response => response.json().data as Hero[])                .catch(this.handleError);   } 

The HttpService inside Angular2 already returns an observable, sou don't need to wrap another Observable around like you did here:

   return Observable.create(observer => {         this.http.get('http://users.org').map(response => response.json() 

Try to follow the guide in link that I provided. You should be just fine when you study it carefully.

---EDIT----

First of all WHERE you log the this.users variable? JavaScript isn't working that way. Your variable is undefined and it's fine, becuase of the code execution order!

Try to do it like this:

  getUsers(): void {         this.userService.getUsers()             .then(users => {                this.users = users                console.log('this.users=' + this.users);             });       } 

See where the console.log(...) is!

Try to resign from toPromise() it's seems to be just for ppl with no RxJs background.

Catch another link: https://scotch.io/tutorials/angular-2-http-requests-with-observables Build your service once again with RxJs observables.

like image 99
jmachnik Avatar answered Oct 02 '22 00:10

jmachnik