Kostas_Me_
Kostas_Me_

Reputation: 113

Return Observable from inside nested callbacks functions

Good afternoon!

I'm currently developing a web app in Angular2/4 and I have a problem with Observables. The goal is, inside a component, to call a function and when that function finishes, I want some code to be executed. So, the code in the "myComp.component.ts" file is:

this.myService.myFunc1().subscribe(() => {
    // this code has to be executed after myFunc1() finishes.
});

The problem is inside the "myFunc1()" function of the "myService.service.ts" file. The structure of this function is the following:

  1. Define the function, which returns an Observable<Status>, where Status object is just { status: 'ok' }.
  2. Call the function "myFunc2()" from another service, which returns an Observable, and do some staff.
  3. Call the function "myFunc3()" from another service, which returns an Observable and has to be executed after "myFunc2()" finishes.
  4. Call the function "myFunc4()" from another service, which returns an Observable and has to be executed after "myFunc3()" finishes.
  5. Return the { status: 'ok' } into the "myComp.component.ts" in order the other code inside the subscribe() to be executed.

So what I need is (3) nested calls of some functions, each and every one of them to be executed after the previous one. The most simple method is given below:

myFunc1(): Observable<Status> {
    // some code and then call of myFunc2()
    this.myService2.myFunc2().subscribe(data => {
       // do some staff here and then call of myFunc3()
       this.myService3.myFunc3().subscribe(data2 => {
          // do some other staff and then call of myFunc4()
          this.myService4.myFunc4().subscribe(data3 => {
             // do staff and then return program flow into the Component
             return Observable.of<Status>({status: 'ok'});
          });
       });
    });
}

But of course the return Observable.of<Status>({status: 'ok'}); doesn't work. I have been searching for a solution on the Internet and other Stackoverflow questions and I found suggestions like use of flatMap(), mergeMap(), switchMap() etc. I think that these solutions cannot be used in my case, because each function has to be executed after the other.

What can I do? What I miss here? Thank you in advance for your help and your time!

Upvotes: 1

Views: 1484

Answers (1)

alexKhymenko
alexKhymenko

Reputation: 5598

What You are looking for is switchMap or mergeMap. switch map is better it will cancel previous request if new comes out.

myFunc1(): Observable<Status> {
    // some code and then call of myFunc2()
    return this.myService2.myFunc2()
      .switchMap(data => {
       // do some staff here and then call of myFunc3()
       return this.myService3.myFunc3()
      }).switchMap(data2 => {
          // do some other staff and then call of myFunc4()
          return this.myService4.myFunc4()
      }).switchMap(data3 => {
             // do staff and then return program flow into the Component
             return Observable.of<Status>({status: 'ok'});
          });
       });
    });
}

Upvotes: 3

Related Questions