订阅observable返回undefined

时间:2017-10-16 11:16:08

标签: javascript angular typescript observable angular2-services

所以我试图订阅一个从本地JSON文件返回数据的简单服务。

我已经设法让服务正常工作,我可以在函数中注销它,但是当我在angular 2组件中订阅服务时,它总是未定义的。我不知道为什么?任何帮助将不胜感激。

API服务

export class ApiService {
   public data: any;

   constructor(private _http: Http) {
   }

   getData(): any {
       return this._http.get('api.json').map((response: Response) => { 
       console.log('in response', response.json()); //This logs the Object
       this.data = response.json();
       return this.data;
   })
   .catch(this.handleError);
   }
}

组件

export class AppComponent {
   public data: any
   public informationData;

   constructor(private _api: ApiService) {}

   public ngOnInit(): void {
      console.log(this.getDataFromService()); // This return undefined
   }

   public getDataFromService() {
      this._api.getData().subscribe(response => {
          this.informationData = response;
          return this.informationData;
      });
   }
}

7 个答案:

答案 0 :(得分:18)

也许有些照片有帮助?

此处的数字表示操作顺序。

发送Http请求 enter image description here

  1. 初始化Component并调用movieService的getMovies方法。
  2. movieService getMovies方法返回一个Observable。此时不是数据。
  3. 组件在返回的Observable上调用subscribe
  4. get请求已提交给服务器进行处理。
  5. ngOnInit方法已完成。
  6. subscribe之后的任何代码都无法访问movies属性,因为尚未返回数据。

    接收Http响应 enter image description here

    在某个晚点......

    1. 电影将返回服务。
    2. 如果进程成功,则执行第一个回调函数。
    3. 本地电影属性被分配给从服务返回的电影。只有在这里才能最终设置电影属性。
    4. 在步骤#8之前尝试访问电影属性会导致错误。

      我们可以在这里访问该值吗? NO enter image description here

      要修复它: enter image description here

答案 1 :(得分:0)

同步和异步功能之间存在问题。您的问题是:getDateFromService是同步的,内部的内容是异步的。因此,当ngOnInit函数调用getDataFromService时,您的代码不会等待异步任务。你getDataFromService需要返回观察者或需要实现API的返回(你需要选择)。

public ngOnInit(): void {
  console.log(this.getDataFromService().subscribe(data => console.log(data)); // This return undefined
}

public getDataFromService() {
  return this._api.getData();
}

答案 2 :(得分:0)

objResponse;
this.service.getData().subscribe((result: any)=> { 
this.objResponse=result;
}

返回不需要的东西

答案 3 :(得分:0)

  

而不是像以前那样登录ngOnInit()方法

 public ngOnInit(): void {
      console.log(this.getDataFromService()); // This return undefined    }
  

将subscribe()方法内的日志记录为

export class AppComponent {
  public data: any
  public informationData;

  constructor(private _api: ApiService) {}

  public ngOnInit(): void {
    this.getDataFromService(); //don't log here, logging here will return undefined
  }

  public getDataFromService() {
    this._api.getData().subscribe(response => {
      this.informationData = response;
      console.log(this.informationData); //log here, like this
      return this.informationData;
    });
  }
}

答案 4 :(得分:0)

您可以这样做:

在您的应用程序组件中:

public getDataFromService() {
  this._api.getData(this);
}


public setData(data: any){
 this.data=data;
}

在您的service / api.ts中:

public getData(obj: appComponentModel){
    this.http.get(url).subscribe(res => obj.setData(res));
}

答案 5 :(得分:-1)

尝试:

getData(): any {
       return this._http.get('api.json');
}

   getData(): any {
           return this._http.get('api.json').map((response: Response) => { 
    response.json();
})

答案 6 :(得分:-2)

把“订阅”想象成一个单独的线程运行,在“订阅”的匿名函数中写下所有需要的东西。只要“数据”可用,它就会在 subscribe 方法中可用。

希望这会有所帮助。