Wait for observable to complete
Asked Answered
M

5

17

I have series of methods which are dependent on completion of other methods.

process1(data: string) : Observable<string> {
   this.dataservice.process(data).subscribe(
            (response) => {
                return response.data;
            }
        );
}

main(data: string) : string {

   var process1Data: string = process1(data); 

   // I would like to wait for process1 method to complete before running process2
   // I do not want to include process2 inside subscribe of process1 because I have to make few more method calls
   var process2Data: string = process2(process1Data);

   var process3Data: string = process3(process2Data);

   ...

}

How can I wait for an observable to complete before calling next method (process2, process3)? (similar like await in c#)

Mccaskill answered 27/7, 2017 at 15:21 Comment(0)
D
13

You might try something like this...

main(data: string) : string {

    process1Data$: Observable<string> = process1(data)
        .take(1)
        .switchMap((process1Data) => return process2(process1Data);
    .
    .
    .
}

Obviously, take(1) assumes that process1(...) resolves to single value and stops. After that it switchMaps to process2 which means it starts emitting whatever observable from process2 gives. If, on the other hand, you want process2 to be ran of each result emitted from process1 then just remove take(1).

Demonolatry answered 27/7, 2017 at 16:21 Comment(0)
B
5

You can use rxjs concat operator. See documentation here. concat

Basically it waits untill the first or source observable returns and then executes next.

update

You can also try operators like switch or switchmap according to your requirements.

Billiot answered 27/7, 2017 at 16:6 Comment(0)
S
3

You can use es6 async/await

async main(data: string): string {
    var process1Data: string = await process1(data).toPromise();
    var process2Data: string = process2(process1Data);
    ...
}
Senarmontite answered 27/7, 2017 at 15:48 Comment(2)
yes, it would work this way however I will have to make all main's calling methods async too. Is it possible to implement this without making main async? I am ok to make process1 async if required.Mccaskill
@Andre that's inaccurate, Observables are interoperable with Promises - see RxJS Observable interop with Promises and Async-AwaitSorghum
E
0

process1 in the original question is confusing as it does not return an Observable<string> (Maybe I'm using another Observable from 'rxjs/Observable').

This is the code I'm referring to (in original question):

process1(data: string) : Observable<string> {
   this.dataservice.process(data).subscribe(
            (response) => {
                return response.data;
            }
        );
}

For me, I changed it to this:

process1(data: string) : Observable<string> {
   return this.dataservice.process(data).map(  //subscribe-->map
            (response) => {
                return response.data;
            }
        );
}

Then to have something happen after process1 completes, just use subscribe like you would with any other Observable:

main(data: string) : string {
   process1(data).subscribe((process1RetVal)=>
   {
         process2(process1RetVal);
   });
}
Electroacoustics answered 27/8, 2018 at 5:31 Comment(0)
R
-1

What you need is the concatMap operator.

Every item that is emitted through the concatMap operator will be executed one by one. You can leverage this to achieve what you want.

Render answered 24/5, 2022 at 12:20 Comment(2)
although this may be a valid pointer, if you want your answer to be useful please explain and give code examples on how to solve it, otherwise the answer is not really useful to most.Urogenital
i was not aware that it is required to give full solutions?Render

© 2022 - 2024 — McMap. All rights reserved.