Angular订阅。无法获取数据

时间:2019-03-01 22:34:51

标签: angular typescript api service

更新 我如何做到这一点如下(滚动到我的答案或这里的链接): https://stackoverflow.com/a/55013081/1729405

我正在尝试在Angular 7中构建APIService。我正在使用“订阅”推送到无法通过其他服务访问的数组。

这是api服务方法:

  getResponse(url):Observable<any> {
    return this.http.post(url, '', {responseType: 'text'});
  }

  getAll() {
      this.getResponse(this.todayApiUrl).subscribe(
        (response) => {
          this.data.push(response);
        });

      return this.data;
  }

这是我尝试在辅助服务中调用它的方式:

export class AdsHealthService {
  today = this.callResponseApiService.getAll();


  constructor(private callResponseApiService: CallResponseApiService) { }

  getHealthValue(interval, type) {
    let obj = this.today;
    console.log(obj);
  }
}

附件console.log()中的响应是我得到的。它看起来像一个数组,但是当我尝试访问第一个元素时,我收到一条undefined消息。我究竟做错了什么?? enter image description here

4 个答案:

答案 0 :(得分:1)

发生这种情况是因为http.post是异步的,您可以通过将getResponse() async变成{{1}到Observable 1}},并在Promise之前添加.toPromise(),因为await不会返回Observable而是原始数据,因此不再需要http.post

getResponse()

答案 1 :(得分:1)

在您的服务中,您需要以下内容:

  async getResponse(url) {
    return await this.http.post(url, '', {responseType: 'text'}).toPromise();
  }

  async getAll(url) {
    return await this.getResponse(url);
  }

在另一个服务/组件中,您可以检索如下的承诺。为了确保您能兑现承诺,您需要使用try catch块。

  async getToday() {
    try {
      let today = await this.yourServiceName.getAll(this.todayApiUrl);
      return today;
    } catch(e) {
        console.log(e);
    }
  }

然后致电:

let data = this.yourServiceName.getToday();
this.data.then((res) => {
// do stuff with 'res' here.
}

没有一种方法可以将值保存在then范围之外。为避免多次访问该API,我设置了一个缓存服务,以便您可以在必要时从缓存中存储/检索。这是我引用的有关缓存的文章的链接:https://hackernoon.com/angular-simple-in-memory-cache-service-on-the-ui-with-rxjs-77f167387e39

这是您可以做的:

  if (!this.cacheService.has('some key')) {
    let data = this.yourServiceName.init();
    this.cacheService.set('some key', data)
  } else {
    let cache = this.cacheService.get('data');
    // do stuff here.
  }

希望有帮助!

答案 2 :(得分:0)

您不会获取数据或数据为null或未定义的数据,因为您的其余端点将在将来返回数据,但是return语句将立即返回。

以下是解决此问题的方法

  • 在模板中使用async管道,在服务中使用.map
  • 使用map
  • 在组件中准备好数据

下面是代码

  // one method is fine to return data from rest endpoint
  getAll(url):Observable<any> {
     return this.http.post(url, '', {responseType: 'text'});
   }

在您的组件类中

export class AdsHealthService {

  constructor(private callResponseApiService: CallResponseApiService) {
     this.callResponseApiService.getAll().subscribe( (today) => {
       let obj = today;
       console.log(obj);
     });
  }

 rawdata = this.callResponseApiService.getAll();


}

如果您直接在模板中显示数据,则可以使用async管道进行操作。

<div>{{rawdata | async}}</div>

答案 3 :(得分:0)

您可以这样做:

在您的应用程序组件中:

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


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

在您的service.ts中:

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

它的格式与您的问题并不完全相同,但任何人都很容易理解。