更新 我如何做到这一点如下(滚动到我的答案或这里的链接): 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
消息。我究竟做错了什么??
答案 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));
}
它的格式与您的问题并不完全相同,但任何人都很容易理解。