@alexig

Как использовать observable в angular2?

Есть такой сервис:
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:extractData@body]: " + body.data[0].name);
    return body.data || { };
  }

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


Из этого сервиса данные забирает такой компонент:
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);
    }

  }

}


В результате исполнения получаю ошибку типа
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:getUsers@1] 
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:extractData@body]: ООО Рога и копыта

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


В логе видно, что внутри subscribe данные доступны и выдаются в консоль.
В компонент же они не попадают вероятно потому, что когда идет отображение в компоненте - Observable еще не вернулся и subscribe (в котором происходит обновление this.users) еще не отработал.

Как сделать чтобы компонент отрабатывал после того как придет Observable?
Или может я что-то упускаю здесь?
  • Вопрос задан
  • 1128 просмотров
Решения вопроса 1
@SergeyBugai
С учетом того что данные вы получаете с сервера то в момент инициализации шаблона переменная users все еще не определена, попробуйте такой синтаксис:
<li *ngFor="let u of users">{{u?.name}}</li>
или используйте пайп asynk
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
Ошибка то судя по всему не тут, шаблон покажите. У вас там может быть есть что-то типа {{users.name}}?
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы