Reputation:
I have a nested subscription in angular component. I can't share the code with you, but I'll try to explain the situation I'm facing. The situation is like this
ParentComponentA
result:any;
mystatus: boolean = false;
@ViewChild(ChildComponentA): childComponentA;
this.myService.getResult().subscribe(res =>{
this.result = res;
// in the first subscribe there will be a lot of calculations based on res
/*the second service will take one of the
values as an argument which will be there in res, let's say a flag*/
this.mySecondService.getStatus(this.result.flag).subscribe(flagSatus => {
this.myStatus = flagStatus; //flagStatus will return true value
/*now here I have a function named myFunction, which will use this.results
values and flagStatus to do some calculation*/
myFunction(this.res.profile, this.myStatus)
});
});
myFunction(profile, status) {
/* here childComponentA is coming undefined
when I'm printing in it console therefore it is not going in if condition*/
if(this.childComponentA) {
}
}
HTML template A
<div *ngIf="myStatus">
<! -- child-comp is selector of ChildComponentA -->
<child-comp> </child-comp>
</div>
Now, this is all working fine, but the flagStatus which I'm getting from inner subscription, I'm using it in html template. The childComponentA is being displayed, but when I do console.log(this.childComponentA) it is coming undefined. This is what my exact problem is, this may be because my initially value of myStatus is false. But when I'm putting whole innersubscription in setTimeOut, everything is working fine, it's going in if condition of myFunction also.
To avoid using setTimeOut, I would like to use rxjs to achieve what I'm trying to do in an efficient manner. I looked up everywhere but couldn't find a example which is similar to mine. From what I found is, we can use switchMap to do what I want. My question is how exactly can I use it or are there any other operators which I can use? Please help me with this.
Upvotes: 0
Views: 1349
Reputation: 148
I've solved this using Rxjs subject, it acts as an event emitter when the observable finishes. If it makes sense to have the last value saved (like if you have an id that will be used in other services) you can use a behaviourSubject. What is the difference between Subject and BehaviorSubject?
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
mySubject = new BehaviorSubject(null);
// This would be the first request that loads data
getData() {
return this.http.get<any>(Services, options).map(
res => {
console.log('res from service', res);
this.mySubject.next(res});
});
}
Now if you have another component that needs this data and was previously loaded, it will still be available
this.service.mySubject.subscribe( (res:any) => {
this.http.get<any>(res.someParam , options).map(
....
});
}
Upvotes: 0
Reputation: 178
you can use switchMap because you are trying to get a result from an observable based on another result from another observable. you can read more about switchMap here. https://www.learnrxjs.io/learn-rxjs/operators/transformation/switchmap
Upvotes: 0
Reputation: 695
You can use mergeMap for subscribing multiple Observable.
const result1$ = this.myService.getResult();
result1$.pipe(
mergeMap(res => this.mySecondService.getStatus(res.flag).pipe(flagSatus => {
this.myFunction(res, status);
})));
Upvotes: 1