8

I have a method that needs to wait for an observable to finish. I know observable are great for returning single pieces of data over time but I need to know when this observable has completely finished returning all of its data so I can run validation code on the object it has returned.

The method getCustom subscribes to an observable run on the supplied url which then returns the observable.

I am not too sure if this is the best way to approach this situation so I would appreciate if anyone could give me any advice or a direction to handle this.

  private validateQuoteRetrievalAnswers(reference: string) {

         // Get the risk from the server
        this.riskManager.getRiskFromServer(reference);

        if (this.riskManager.risk) {
            // Validate risk that was returned
        }
    }
getRiskFromServer(quoteReference: string) {

    this.riskService.getCustom("Url").subscribe => {
        // need to know when the observable has returned the risk
    });

}
n00dl3
  • 21,213
  • 7
  • 66
  • 76
  • 3
    You can't wait for an observable to finish. You can only subscribe and pass a callback to `subscribe(...)` that is called when the data arrives. – Günter Zöchbauer Apr 12 '17 at 10:21
  • These two methods are both in different services, could you possibly give an example of what you mean? –  Apr 12 '17 at 10:38
  • 3
    Then don't call `subscribe()` in the service (just return the observable `return this.riskService.getCustom("Url");` and in the service where you need the data use `getRiskFromServer(...).subscribe(...)` See also http://stackoverflow.com/questions/36271899/what-is-the-correct-way-to-share-the-result-of-an-angular-2-http-network-call-in/36291681#36291681 – Günter Zöchbauer Apr 12 '17 at 10:39

1 Answers1

8

how i would tackle this challenge:

Query you back-end and when we've got what we need push it to a Subject

riskSubject = new Subject<Risk>();

getRiskFromServer(quoteReference: string) {
  this.riskService.getCustom("Url")
  .subscribe( 
    data => { this.riskSubject.next(data); },
    error => { console.log(error) }
 });
}

and then subscribe to subject and wait until you get what you need and start validating

private validateQuoteRetrievalAnswers(reference: string) {

         // Get the risk from the server
        this.riskManager.getRiskFromServer(reference);
        // subscribe to subject
        this.riskManager.riskSubject.subscribe(
         data => {
           //do your validation
        })
}

The heart of an observable data service is the RxJs Subject. Subjects implement both the Observer and the Observable interfaces, meaning that we can use them to both emit values and register subscriptors.

The subject is nothing more than a traditional event bus, but much more powerful as it provides all the RxJs functional operators with it. But at its heart, we simply use it to subscribe just like a regular observable

source: angular-university.io

OR you can use Observable.fromPromise(promise) but this will make things a bit more complicated to understand if you are new to ng2

VikingCode
  • 1,022
  • 1
  • 7
  • 20
  • This is exactly what I ended up doing, my issue was I was trying to do specific logic after the success handler off the riskSubject,subscribe(). Instead I just performed my operations inside the data = { } code block. It was more my mistake for not understanding the best away to use the availability of an observable –  Apr 13 '17 at 10:50