Reputation: 689
I have this piece of code:
ngOnInit(): void
{
this.categories = this.categoryService.getCategories();
var example = this.categories.flatMap((categor) => categor.map((categories) => {
var links = this.categoryService.countCategoryLinks(categories.id)
.subscribe(valeur => console.log(valeur));
return categories.id
}));
}
The result are two observables. One consists in a list of categories. The second one is the number of items for a particular categories.id.
My question is as follow:
How could I get all this information structured in a particular data structure? I would like to store categories and the number of items per category in the same data structure to be able to show them up in my TS component.
I went step by step trying to fix my issues and I went to have the following code that is almost the solution:
this.categories = this.categoryService.getCategories();
var example = this.categories.mergeMap((categor) => categor.map((myCateg) =>
{
this.categoryService.countCategoryLinks(myCateg.id)
.map(numlinks => Object.assign(myCateg,{numLinks: numlinks}))
.subscribe(valeur => console.log(valeur));
return myCateg.id
}));
It gives the following output:
Where numLinks is still an object... (containing my count value) Any idea on how to transform it to a json property like categoryName or id??
Thanks in advance and Regards,
Here is the solution to the problem:
ngOnInit(): void
{
this.categories = this.categoryService.getCategories();
const example = this.categories
.mergeMap((categor) => categor
.map((myCateg) => {
this.categoryService.countCategoryLinks(myCateg.id)
.map(numlinks => {
myCateg.numlinks = numlinks.count;
return myCateg;
})
//Object.assign(myCateg,{numLinks: numlinks}))
.subscribe(value => console.log(value));
return myCateg
}));
example.subscribe(val => console.log("value2: "+val));
}
Upvotes: 1
Views: 3333
Reputation: 14077
Once more, the solution comes from the mergeMap()
operator. :-)
this.categoryService.getCategories()
.mergeMap(val => val) // "Flatten" the categories array
.mergeMap(category =>
this.categoryService.countCategoryLinks(category.id)
// Write the number of links on the `category` object
.map(numLinks => Object.assign(category, {numLinks: numLinks}))
)
.toArray()
.subscribe(allCategoriesWithNumLinks => console.log(allCategoriesWithNumLinks));
I'm not going into the specifics (the first mergeMap
to flatten the array, Object.assign()
to produce the final object) since it seems like we covered all that in a previous thread we had, but feel free to ask questions if anything is unclear.
Philippe's questions:
getCategories()
emits a SINGLE array containing all the categories. Since you want to run an HTTP request for each category, it's more convenient to have an observable emitting each category individually. That's what the first mergeMap()
does: it transforms Observable<Category[]>
into Observable<Category>
.Object.assign
does: it writes the number of links found for each category on the category
object itself. This way, you end up with ONE object containing the information from TWO observables (category + numLinks).Upvotes: 2