2

How can I execute observable methods that depends on the sequence in a clear way in typescript?

example:

Init(){
    this.methodThatUseObservable();
    this.methodThatShouldExecuteAfter();
    this.anotherMethod();
    ... (continue)
}

And in each of those methods I have inside an obsevable method and subscribe.

methodThatUseObservable(){
   this.service1.get().subscribe(
      (value1) => {
         this.value1 = value1;
      }
   )
}
methodThatShouldExecuteAfter(){
   this.service2.get(this.value1).subscribe(  //depends on the first
      (value2) => {
         this.value2 = value2;
      }
   )
}
anotherMethod(){
   this.service3.get(this.value2).subscribe(  //depends on the second
      (value3) => {
         this.value3 = value3;
      }
   )
}
...(so on)

Of cource I could do:

Init(){
    this.methodThatUseObservable();
}

And in each of those methods other methods that depends:

methodThatUseObservable(){
   this.service1.get().subscribe(
      (value1) => {
         this.value1 = value1;
         this.methodThatShouldExecuteAfter();
      }
   )
}
methodThatShouldExecuteAfter(){
   this.service2.get(this.value1).subscribe(  //depends on the first
      (value2) => {
         this.value2 = value2;
         this.anotherMethod();
      }
   )
}
anotherMethod(){
   this.service3.get(this.value2).subscribe(  //depends on the second
      (value3) => {
         this.value3 = value3;
         ...(and so on)
      }
   )
}

But I don't feel it very clear, in this way I think the sequence is not very clear.

Maybe the solution is returning a promize and executing then method?

    this.methodThatUseObservable().then(()=>{
       this.methodThatShouldExecuteAfter();
    }).then(()=>{
       this.anotherMethod();
    })

I don't know if such changes in the structure is possible, please help.

Yugo Harago
  • 321
  • 3
  • 11

2 Answers2

2

I'm not sure if this is a best practice in your example, however, what I do is wrap each method in a promise, then use async/await in order to chain them in a readable way. For example, in Angular:

async ngOnInit(){
    try{
        await this.methodThatUseObservable();
        await this.method2();
        await this.method3();
        console.log("Done");
    }
    catch(e){
        //Handle errors
    }
}

methodThatUseObservable() : Promise<{}>{
    return new Promise(
        (resolve, reject) => {
            this.service1.get().subscribe(
                value1 => {
                    this.value1 = value1;
                    resolve();
                },
                error => {
                    reject('Error!');
                }
            )
        }
    )
}

...Same for method2, method3
noamyg
  • 2,747
  • 1
  • 23
  • 44
  • think he is looking for observable execution in sequence – Fan Cheung Sep 11 '19 at 17:06
  • I believe observables have a build in way to convert to promise [toPromise](https://www.learnrxjs.io/operators/utility/topromise.html) –  Sep 11 '19 at 17:07
  • @ProfessorAllman in my example you're 1. Keeping the ngOnInit clean from handling the subscription result 2. You're keeping the subscription alive while toPromise() will turn it into a promise. – noamyg Sep 11 '19 at 17:15
  • 1
    @noamyg Thanks so much! I didn't know that I could use Promise that way – Yugo Harago Sep 11 '19 at 17:57
1

Try this:

import {concat, of} from "rxjs";

concat(
  of(() => this.methodThatUseObservable()),
  of(() => this.methodThatShouldExecuteAfter()),
  of(() => this.anotherMethod())
  ).subscribe(() => {}, error => {}, () => this.doYourStuff());
D Pro
  • 1,756
  • 1
  • 8
  • 15