Dyd666
Dyd666

Reputation: 735

Get event from inner observable

public testFunction(name: string, model: string): Observable<any> {
       return this.doSomething(name, model)
              .flatMap((result: any) => {
                   return this.doSomethingElse()... // returning an Observable<any>
               });
}

That doSomething is a HTTP call, actually returning an Observable by itself. Here is were i call that method:

public foo () {
    this.testFunction(name, model)
                     .subscribe(
                     (result) => {
                         // do something
                     },
                     (error) => {
                         // do something wit the error
                     });
}

Problem is: how can i catch if the doSomething HTTP call went good or bad from within foo? I do not want to use a Subject or Behaviour subject since testFunction is part of a service and foo is on a component. I mean, don't want to add a "superstructure" to achieve it.

Upvotes: 1

Views: 95

Answers (3)

Diego Bonura
Diego Bonura

Reputation: 199

You could check my solution on:

Notify from inner flatMap

Quite simple and you don't have to merge different observables.

Upvotes: 1

Dyd666
Dyd666

Reputation: 735

Found a solution: by splitting that big observable i can handle two differents onNext instead of just one. This allows me to know when the first method (doSomething) ends.
Here a plunkr: https://plnkr.co/edit/crWpj8deQzePCrTtYz6k?p=preview

public testFunction(name: string, model: string): Observable<any> {
   let obs1 = this.doSomething(name, model);
   let obs2 = obs1.flatMap((data) => { 
                 return this.doSomethingElse() //[...]
           });
   let merge = Observable.merge(obs1, obs2);
   return merge  
}
public foo () {
    this.testFunction(name, model)
                     .subscribe(
                     (result) => {
                         // 1 - Obs1 next
                         // 2 - Obs2 next
                     },
                     (error) => {
                         // do something wit the error
                     });
}

Upvotes: 1

Mark van Straten
Mark van Straten

Reputation: 9425

Your current code does exactly what you want. If an onError is raised in DoSomethingElse it is emitted to the main stream and will end up in your subscription onError in the foo() method.

If you want to have more control over how your succes/error is propagated you could also do something like this:

public testFunction(name: string, model: string): Observable<any> {
  return this.doSomething(name, model)
    .flatMap((result: any) => this.doSomethingElse()
        .map((doSomethingElseResult:any) => ({ result:'succes', data: doSomethingElseResult })
        .catch(err => Rx.Observable.just({ result: 'do-something-else-error', error: err }))
    )
    .catch(err => Rx.Observable.just({ result: 'do-something-error', error:err });
}

This will convert all errors to onNext values which have a type for you to handle upon if the type is do-something-else-error

Upvotes: 0

Related Questions