A
A
alexig2017-06-08 23:14:40
Angular
alexig, 2017-06-08 23:14:40

How to use observable in angular2?

There is such a service:

import { Injectable } from '@angular/core';
import {Headers, Http, Response} from "@angular/http";
import {Observable} from 'rxjs/Observable';
import "rxjs/add/operator/map";
import 'rxjs/add/operator/catch';
import { User } from './user';

@Injectable()
export class UserService {
  private usersUrl = 'api/users';
  private headers = new Headers({'Content-Type': 'application/json'});

  constructor(private http: Http){}

  private extractData(res: Response) {
    let body = res.json();
    console.log("[user.service:[email protected]]: " + body.data[0].name);
    return body.data || { };
  }

  getUsers(): Observable<User[]> {
    return this.http.get(this.usersUrl)
      .map(this.extractData)
      .catch(this.handleError);
  }

The following component takes data from this service:
import { Component, OnInit } from '@angular/core';
import { User } from '../user';
import { UserService } from '../user.service';

@Component({
  selector: 'user',
  templateUrl: './user.component.html'
})
export class UserComponent implements OnInit {
  user: User;
  users: User[];

  constructor(private userService: UserService) { }

  ngOnInit(): void { this.getUsers() }

  getUsers() {
    this.userService.getUsers()
      .subscribe((users) => {
        this.users = users;
        for (let u of users) {
          console.log("[user.component:getUsers] forInSubscribe: " + u.id + ":" + u.name);
        }
      });

    for (let u of this.users) {
      console.log("[user.component:getUsers] for: " + u.id + ":" + u.name);
    }

  }

}

As a result of execution I get an error like
Navigated to http://localhost:4200/
core.es5.js:3046 Angular is running in the development mode. Call enableProdMode() to enable the production mode.

user.service.ts:32 [user.service:[email protected]] 
usercomponent.html:12 ERROR TypeError: Cannot read property 'name' of undefined
    at Object.eval [as updateRenderer] (usercomponent.html:12)
    at Object.debugUpdateRenderer [as updateRenderer] (core.es5.js:12844)
    at checkAndUpdateView (core.es5.js:12149)
    at callViewAction (core.es5.js:12507)
    at execComponentViewsAction (core.es5.js:12439)
    at checkAndUpdateView (core.es5.js:12150)
    at callViewAction (core.es5.js:12507)
    at execEmbeddedViewsAction (core.es5.js:12465)
    at checkAndUpdateView (core.es5.js:12145)
    at callViewAction (core.es5.js:12507)

user.service.ts:27 [user.service:[email protected]]: ООО Рога и копыта

user.component.ts:25 [user.component:getUser] forInSubscribe: 11:ООО Рога и копыта
user.component.ts:25 [user.component:getUser] forInSubscribe: 12:user2
user.component.ts:25 [user.component:getUser] forInSubscribe: 13:u3
user.component.ts:25 [user.component:getUser] forInSubscribe: 14:u4
user.component.ts:25 [user.component:getUser] forInSubscribe: 15:u5

usercomponent.html:12 ERROR TypeError: Cannot read property 'name' of undefined
    at Object.eval [as updateRenderer] (usercomponent.html:12)
    at Object.debugUpdateRenderer [as updateRenderer] (core.es5.js:12844)
    at checkAndUpdateView (core.es5.js:12149)
    at callViewAction (core.es5.js:12507)
    at execComponentViewsAction (core.es5.js:12439)
    at checkAndUpdateView (core.es5.js:12150)
    at callViewAction (core.es5.js:12507)
    at execEmbeddedViewsAction (core.es5.js:12465)
    at checkAndUpdateView (core.es5.js:12145)
    at callViewAction (core.es5.js:12507)
View_usercomponent_0 @ usercomponent.html:12

The log shows that inside the subscribe data is available and output to the console.
They do not get into the component, probably because when the display is in the component, the Observable has not yet returned and the subscribe (in which this.users is updated) has not yet worked.
How to make the component work after the Observable arrives?
Or maybe I'm missing something here?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
S
SergeyBugai, 2017-06-09
@alexig

Considering that you receive data from the server, at the time of template initialization, the users variable is still not defined, try this syntax: or use the async pipe

N
Nicholas, 2017-06-08
@healqq

The error is apparently not here, show the template. Do you have something like {{users.name}} there?

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question