Angular 角度订阅。Can';我们无法获取数据

Angular 角度订阅。Can';我们无法获取数据,angular,typescript,api,service,Angular,Typescript,Api,Service,更新 下面是我是如何做到这一点的(滚动至我的答案或链接): 我正在尝试在Angular 7中构建一个APIService。我正在使用subscribe推送到一个无法通过其他服务访问的阵列 以下是api服务方法: getResponse(url):Observable<any> { return this.http.post(url, '', {responseType: 'text'}); } getAll() { this.getResponse

更新 下面是我是如何做到这一点的(滚动至我的答案或链接):

我正在尝试在Angular 7中构建一个APIService。我正在使用subscribe推送到一个无法通过其他服务访问的阵列

以下是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;
  }
在所附的图像中,是我在
console.log()
响应时得到的结果。它看起来像一个数组,但当我尝试访问第一个元素时,会收到一条
undefined
消息。我做错了什么??
之所以发生这种情况,是因为
http.post
是异步的,您可以通过使
getResponse()
异步,将
可观察的
转换为
承诺
,通过
.toPromise()
并在
http.post
之前添加
wait
,因为
getResponse()
将不返回可观察的原始数据,因此不再需要
.subscribe()

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

  async getAll() {
    this.data = await this.getResponse('some url');
    return this.data
  }
  async some() {
    const data = await this.getAll();
    console.log(data);
    console.log(this.data);
  }

您没有将数据或数据获取为null或未定义,因为您的rest端点将在将来返回数据,但您的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'});
   }
如果您直接在模板中显示数据,则可以使用
async
pipe进行显示


{{rawdata | async}

在您的服务中,您需要以下几点:

  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,我设置了一个缓存服务,以便在必要时可以从缓存中存储/检索。以下是我在缓存时引用的文章的链接:

以下是您可以做的:

  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.
  }

希望有帮助

您可以这样做:

在应用程序组件中:

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


public setData(data: any){
 this.data=data;
}
为您服务。ts:

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

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

我得到了您提供的解决方案的承诺。你如何从承诺中获得价值?async getAll(){let promise=this.http.post(this.todayApiUrl,,{responseType:'text'}).toPromise();promise.then(函数(值){return value;});this.today=wait promise;console.log(this.today);//this返回字符串值返回this.today;}在AdsHealthService类中:this.data=this.CallResponseAservice.getAll();console.log(this.data);//这将返回承诺对象而不是字符串,谢谢!我已经更新了答案。谢谢你指出这一点。因为
getAll()
async
你也必须用wait调用它。当在async函数some()之外引用this.data时,我仍然没有定义。有没有一种方法可以在异步函数之外获取字符串值(因为所有异步函数都返回一个承诺)?您想对这些数据做什么?只需在UI中显示它们或进行一些修改?明白了!答案如下:)我可以用承诺来代替。出于某种非常奇怪的原因,可观测数据不会以我能够获得数据的方式返回。不知道为什么。感谢您的反馈!首先,欢迎来到Stack。感谢你的回答。如果我再遇到这种情况,我会查看您的解决方案。:)自从它发布以来,我就没碰过它。
public getDataFromService() {
  this._api.getData(this);
}


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