订阅 observable 返回 undefined

IT技术 javascript angular typescript observable angular2-services
2021-03-14 19:46:33

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

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

接口服务

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;
      });
   }
}
6个回答

也许一些图片有帮助?

这里的数字表示操作的顺序。

发送 Http 请求 在此处输入图片说明

  1. 组件被初始化并调用movieService 的getMovies 方法。
  2. movieService getMovies 方法返回一个 Observable。不是此时的数据。
  3. 组件调用subscribe返回的 Observable。
  4. get请求被提交给服务器进行处理。
  5. ngOnInit方法完成。

由于尚未返回数据,因此此处之后的任何代码subscribe都无法访问该movies属性。

接收 Http 响应 在此处输入图片说明

在稍后的某个时间点......

  1. 电影将返回给服务。
  2. 如果处理成功,则执行第一个回调函数。
  3. 本地电影属性分配给从服务返回的电影。只有在这里最终设置了电影属性。

在第 8 步之前尝试访问电影属性会导致错误。

我们可以访问这里的值吗? 在此处输入图片说明

要解决这个问题: 在此处输入图片说明

这写得非常好,并得到了证明。谢谢@DeborahK!
2021-04-23 19:46:33
经过几天的搜索答案,我找到了您的帖子。非常感谢您的黛博拉!这就是我正在寻找的。但是你能告诉我如何解析/操作来自 this.movi​​es 的数据吗?我需要收集它并使用chart.js/ng图表显示在图表中
2021-05-03 19:46:33
这似乎不起作用。调用 this.movi​​es.length,仍然没有填充我的 html:<li *ngFor="let m of movies">{{m.name}}</li> 结果是 <li _ngcontent-c4></li> 的列表li> 没有名字。即使添加 {{m.name|async}} 也没有成功。
2021-05-04 19:46:33
多么美妙的解释!任何在异步问题上挣扎的人都应该看看这个回复。
2021-05-15 19:46:33
这不是这个例子的重点。调用this.movies.length不会导致列表填充。调用.subscribe和 设置this.movies = movies会导致this.movies填充。这篇文章试图说明为什么你不能得到可观察范围之外的长度。尝试发布一个新问题并展示您的一些代码。标记我,我去看看。
2021-05-21 19:46:33
objResponse;
this.service.getData().subscribe((result: any)=> { 
this.objResponse=result;
}

不需要退货

你可以这样做:

在您的应用程序组件中:

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


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

在您的服务/api.ts 中:

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

尝试:

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

或者

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

您在同步和异步功能之间遇到了问题。你的问题是: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();
}
你想从哪里得到你的 api 的响应?因为您的问题是您使用同步/异步功能。如果在您的class中有undefined,则可能是您的class在执行之前不等待异步调用响应console.log
2021-04-24 19:46:33
这很有效,但是当我尝试将data添加到类变量时,它仍然返回 undefined
2021-05-02 19:46:33