Reputation: 2171
In one of my route resolver, I want to get a list of Animals (Animal[]) returned by an API Call. For each animal, I need an extra API call to get the breed name. I tried this :
return this.apiService.get('/api/v1/website/' + environment.web_id + '/useraccount/' + user.id + '/animal').pipe(
map(animals => animals.map(animalObs => {
// return animalObs;
return animalObs.pipe(
map((animal: Animal) => {
animal.ani_breed = this.breedService.get(animal.anb_id).pipe(
map(breed => {
return breed.anb_name;
})
);
return animal;
}),
);
})),
);
But I get an error when compiling : Type 'Observable' is not assignable to type 'string'. [2322]
I think I am missing something... Please help!
Upvotes: 0
Views: 2386
Reputation: 2918
I think what you need is a mergeMap
which merge your current request to another request that will request all the returned animals using forkJoin
and combine it together.
getAnimals = () => this.apiService.get('/api/v1/website/' + environment.web_id + '/useraccount/' + user.id + '/animal').pipe(
mergeMap(animals =>
Observable.create((observer: Observer<any[]>) => {
const animals$ = animals.map(
animal => this.breedService.get(animal.anb_id).pipe(
map(breed => {
return {
...animal,
breed_name: breed.anb_name
}
})
)
);
forkJoin(animals$).subscribe(result => {
observer.next(result);
observer.complete();
});
}))
);
More about forkJoin and mergeMap
https://www.learnrxjs.io/operators/combination/forkjoin.html
https://www.learnrxjs.io/operators/transformation/mergemap.html
EDIT
What you want to do to get the animal and its breed name is return all of the animals property using spread operator and assign the bread name next to it.
map(breed => {
return {
...animal,
breed_name: breed.anb_name
}
})
FINAL EDIT
Spread operator allows you to enumerate all of the objects property. it has the same output as the code below but in a different procedure.
map(breed => {
animal.breed_name = breed.anb_name;
return animal;
})
Upvotes: 2
Reputation: 96969
The actual implementation depends on whether you want to run requests in sequence or in parallel but you can do it example like the following:
this.apiService.get('/api/v1/website/' + environment.web_id + '/useraccount/' + user.id + '/animal').pipe(
mergeMap(animals => {
const animals$ = animals.map(animal => this.breedService.get(animal.anb_id).pipe(
map(breed => {
animal.ani_breed = breed;
return animal;
})
))
return forkJoin(...animals$);
}),
);
Upvotes: 7