user5368536
user5368536

Reputation:

nested subscription, inner subscription is dependent on outer subscription

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

Answers (3)

Jaime FH
Jaime FH

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

Muhannad
Muhannad

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

Durgesh Pal
Durgesh Pal

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

Related Questions