Reputation: 1828
I have a component which retrieves its business object from a single HTTP request, and then has several subsequent requests to populate drop-down lists. The arguments in those subsequent requests consist of data from the business object, so those requests can not begin until the first one completes.
Given an example resolver PersonResolver
, this is the flow I want to achieve:
this.personService.getPersonData()
. Returns type Observable<PersonModel>
.PersonModel
instance, which we'll call personData
, to call this.personService.getAdditionalData1(personData.foo)
and this.personService.getAdditionalData2(personData.bar)
. Both return type any[]
.Observable<PersonModel, any[], any[]>
from the resolve
method.I would like to implement this into the component's resolver, but I am having a tough time wrapping my head around the correct usage of RxJS I need for the job.
Here's what I've got so far. I got stuck pretty quick.
constructor(private personService: PersonService) { }
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<PersonModel, any[], any[]> | Observable<Observable<PersonModel, any[], any[]>> | Promise<Observable<PersonModel, any[], any[]>> {
this.personService.getPersonData().subscribe(personData => {
// what to put in here?
});
}
Upvotes: 2
Views: 5078
Reputation: 7632
First you need to use mergeMap
in order to pass the model PersonModel
from first call. Then you need to use zip
to get all of the result together in one array.
this.personService.getPersonData.pipe(
mergeMap(
personData => zip(
of(personData),
of(getAdditionalData1(personData.foo)),
of(getAdditionalData2(personData.bar))
)
)
).subscribe(allData => {
// here you will have all of the data placed in 'allData' param
});
See this simple StackBlitz DEMO to see this in action
Upvotes: 2
Reputation: 365
Yet another version
this.personService
.getPersonData()
.pipe(
mergeMap(personData =>
merge(
this.personService.getAdditionalData1(personData.foo),
this.personService.getAdditionalData2(personData.bar)
)
)
)
.subscribe(
r => console.log('Response', r),
e => console.log(e),
() => console.log('Done')
);
Upvotes: 0
Reputation: 15912
Try something like this...
Note: READ THIS
constructor(private personService: PersonService) { }
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<PersonModel, any[], any[]> | Observable<Observable<PersonModel, any[], any[]>> | Promise<Observable<PersonModel, any[], any[]>> {
return this.personService.getPersonData().pipe(
mergeMap(personData => this.personService.getAdditionalData1(personData.foo)),
mergeMap(this.personService.getAdditionalData2(personData.bar)));
}
Upvotes: 1