Angular2 http observables - how to work with undefined type

拥有回忆 提交于 2019-12-06 07:55:52

With this code

ngOnInit() {
  this._examsService.getExam()
    .subscribe(response => this.exam = response);
  console.log(this.exam.length);  //this fails
}

the first line sends the request this._examsService.getExam() .subscribe(...) and registers interest in the response, then console.log(this.exam.length) is executed, but at this time respone => this.exam = response hasn't been execute yet, because getExam() is not yet done connecting to the server and receiving the response.

You need to stay in the chain of events to work with the data that is returned eventually, like:

ngOnInit() {
  this._examsService.getExam()
    .subscribe(response => {
      this.exam = response;
      console.log(this.exam.length);  //this shoudn't fail anymore
    });
}

I don't know if this solves your problem but your question doesn't provide enough information about your requirements for a more elaborate solution.

Thierry Templier

I think that the following case is the normal behavior:

ngOnInit() {
  this._examsService.getExam()
    .subscribe(response => this.exam = response);
  console.log(this.exam.length);  //this fails
}

because you try to access the length property on the exam object that will set later and when the response will be there (in the subscribe method).

That said, when an error is thrown within the observable, the map operator isn't called. If you want to transform the error response, you can leverage the catch operator, as described below:

this._examsService.getExam()
    .subscribe(
      // Success
      response => this.exam = response,
      // Failure
      response => {
        // Do something
      });

and the corresponding service code:

getExam() {
  return this.http.get('http://...')
           .map(res = > res.json())
           .catch(res => {
             // If you want to extract the JSON error
             // message from the response
             return Observable.throw(res.json());
           });
}

Otherwise you can also leverage the async pipe to directly set the observable on the component and not do the subscribe:

this.exam = this._examsService.getExam();

and in the associated template

<ul>
  <li *ngFor="#e of exam | async">{{e.name}}</li>
</ul>

Hope it helps you, Thierry

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!