//This is a function that is in my data service (in Angular) that basically gets data and puts it in an array
getTenantData() {
//This is the function that is called by app.component.ts
//It's job is to get data from the tenants collection and map it to an array called tenants
this.afs //afs is simply what i named the Firebase db in my constructor
.collection('tenants')
.snapshotChanges()
.subscribe(values => {
this.tenants = values.map(value => {
return {
id: value.payload.doc.id,
...value.payload.doc.data()
};
});
});
}
//Then if I create a function that performs some 'work' on the tenants array in another component like so
filterMyArray() {
this.ad.tenants.filter(values => { //ad is simply what i called the dataservice in the constructor
if (values.id == 'Some Value') {
this.filteredArray.push(values);
}
});
console.log(this.filteredArray);
}
//This works fine if I call it using some manual 'after load' approach (like clicking a button)
//Doesn't work if I call it in ngOnInit for instance as tenants hasn't been populated yet
//Throws typeerror cannot read property filter of undefined etc.
//So challenge is how do I get the second function to wait for the first
//Keep in mind first function is in a service not in the same component as second function
我一直在遇到需要在构建Angular应用程序时处理异步数据的用例。我已经采用了许多策略来处理事情(异步管道,ngIf等待某些变量准备就绪等)但我觉得我错过了一些东西。以下是最新挑战的具体内容......我有一个从Firebase填充的阵列。这是在加载应用程序时通过函数调用完成的。我们调用数组'sourceArray'
然后,我想在该数组上做一些“工作”,以便在其他组件中播放内容元素。例如,对该阵列执行“过滤器”并根据这些结果创建新数组。
我一直在遇到的挑战(这只是最新的例子)是当我调用在sourceArray上执行'其他工作'的函数时,我得到错误,说blah blah是未定义的,因为它还没有完全填充来自firebase 。所以要简单地解决这个问题...... - 源变量是从需要一些'时间'的东西填充的 - 只有'在'完全填充之后才能对该源变量进行处理
我已经阅读了使用生命周期钩子(即将依赖函数放在源函数之后运行的钩子中)等等,并且使用该策略的成功有限。另外值得注意的是,我正在订阅源阵列中的firebase数据。
我还调查过可能使用async和await但是我真的不明白我将如何应用于这个用例。如果这还不够,任何建议都会很感激,并乐意提供更多细节。
// This is how you can await a call from firebase
// & later do something after call is completed
// write
async function writeData (userId, name, email, imageUrl) {
await firebase.database().ref('users/' + userId).set({
username: name,
email: email,
profile_picture : imageUrl
});
// do something when after is executed
}
// read
async function readData (userId) {
let response = await firebase.database().ref('/users/' + userId).once('value')
console.log(response.val())
// do something after above is executed
}
首先,您没有按预期使用filter()
方法。你正在使用它像你如何使用map()
。你可以做到
filterMyArray() {
this.filteredArray = this.ad.tenants.filter(values => values.id == 'Some Value');
console.log(this.filteredArray);
}
对于您主要关心的问题,您可以在服务中设置一个观察程序,在填充原始数组时过滤掉它。
constructor() {
this.setupWatcher();
}
setupWatcher() {
interval(1000).pipe(
switchMap(() => of(this.ad.tenants)),
filter(response => response && response.length > 0),
take(1))
.subscribe((input: Tenants[]) => {
//do stuff
this.filterMyArray(input);
});
}
然后,
filterMyArray(originalArray: Tenants[]) {
this.filteredArray = originalArray.filter(values => values.id == 'Some Value');
console.log(this.filteredArray);
}