我对Typescript / ionic 4非常陌生。我试图访问存储在Firebase中的数据并在我的Typescript文件中使用它。在.subscribe中时,我可以按要求显示数据。但这不是我想要的。我需要在page.ts上的.subscribe之外执行计算。
我已经看到许多类似的问题,但是我似乎找不到解决方法。
这是我的 Typescript 服务文件
export interface Place{
title: string;
type: string;
latitude: number;
longitude: number;
}
export class PlaceService {
placess: Place[];
place: Place;
private placesCollection: AngularFirestoreCollection<Place>;
private places: Observable<Place[]>;
constructor(db: AngularFirestore) {
this.placesCollection = db.collection<Place>('places');
this.places = this.placesCollection.snapshotChanges().pipe(
map(actions =>{
return actions.map(a => {
const data = a.payload.doc.data();
const id = a.payload.doc.id;
return{ id, ...data};
});
})
);
}
getPlaces() {
return this.places;
}
}
和我页面中的相关部分打字稿
import { PlaceService, Place } from '../services/place.service';
places: Place[];
ngOnInit() {
this.placeService.getPlaces()
.subscribe(res =>{
this.places = res;
console.log(this.places[0].title);//WORKS
});
console.log(this.places[0].title);//FAILED
}
我收到以下错误消息:
MapPage_Host.ngfactory.js? [sm]:1 ERROR TypeError: Cannot read property '0' of undefined
答案 0 :(得分:0)
.subscribe方法必须完成(ajax请求必须为200-OK),可以在subscribe方法内部将其存储到本地变量中,然后可以进行进一步的修改。
您不能使用没有数据的变量。
this.placeService.getPlaces()
.subscribe(res =>{
this.places = res;
});
将花费几秒钟来完成ajax调用并获取响应并将其存储在“位置”中。
解决方法(不推荐),使用set timeout function
等待至少2秒钟。增加秒数,直到找到完成请求和响应的最小秒数。
然后您可以在this.places
上进行一些计算。
答案 1 :(得分:0)
您的问题是您的代码在编写时就可以工作。页面初始化时,将调用ngOnInit
。代码内部进入第一个元素(this.placeService.getPlaces()...),然后立即进入第二个元素(console.log(this.places [0])。这引发了错误,因为{{1 }}变量尚未从您对placeService的调用中设置,并且当前为places
。
undefined
如果在设置ngOnInit() {
this.placeService.getPlaces() // called first
.subscribe(res =>{
this.places = res;
console.log(this.places[0].title);
});
console.log(this.places[0].title); // called second (undefined error)
}
变量后调用函数,第二个console.log()将起作用。
places