I am trying to get data from one subscription and based on the data, I am calling nested subscription to add to the data object. This is how my function looks like:
this.subCatSubscription = this.afDatabase.list('/sub-categories/').snapshotChanges().subscribe((subCat: any) => {
this.categories = [];
subCat.forEach( sc => {
if(sc.payload.val().category) {
this.cat1Subscription = this.afDatabase.list('/categories/').snapshotChanges().subscribe((cat: any) => {
cat.forEach(c => {
if(c.key === sc.payload.val().category) {
this.categories.push({ key: sc.key, ...sc.payload.val(), parentCatName: c.payload.val().name });
//this.categories.sort((a, b) => a.name.localeCompare(b.name));
}
});
});
} else {
this.categories.push({ key: sc.key, ...sc.payload.val() });
//this.categories.sort((a, b) => a.name.localeCompare(b.name));
}
console.log(this.categories)
});
})
Is there any way to combine the two above subscription and get the desired data based on the condition I have?
Thanks.
When you remove the observables from your example, what you're trying to do is create an array of objects while some are mutated from a second array. What I've provided is the following steps.
For step 3 (Get the parent category data) we can do this with a simple switchMap()
.
this.categories$ = this.afDatabase
.list("/sub-categories")
.snapshotChanges()
.pipe(
map(subCategories=>
subCategories.map(sc=>({ key: sc.key, ...sc.payload.val() }))
),
switchMap(categories=>this.afDatabase
.list("/categories/")
.snapshotChanges()
.pipe(
map(parent=>
categories.map(c=>{
const match = parent.find(pc=>pc.key === c.category);
return !!match ? {...c, parentCatName: match.payload.val().name} : c
})
)
)
)
);
Now, we're only requesting /categores/
once instead of multiple times for each match.