David
David

Reputation: 3604

rxJS observable to repeat call every time condition is met in Angular 2

I'd basically like to implement an observable pool consumer.

So, a service makes an http call to retrieve a number of results and then a component is consuming those results one by one. When the service detects that is running out of results it will make a call again to the server for a number of new results.

I started trying to make single http calls and subscribe and unsubscribe every time, but it seems quite messy and confusing.

I'd like something like this:

this.http
  .post(API, postData)
  .map((response: Response) => response.json())
  .subscribe(data => this.saveData(data))
  .repeat(when_certain_condition)

Is there any way to achieve this? I read about repeat but it seems like you need to provide the value to be repeated, so it doesn´t seem like the way to go.

Any ideas? Thanks

Upvotes: 5

Views: 5015

Answers (2)

Max
Max

Reputation: 2040

I faced the very same situation, and I solved with the following approach.

this.http
  .post(API, postData)
  .map((response: Response) => response.json())
  .delay(2000)
  .flatMap(data => {
    this.saveData(data);
    if (when_certain_condition) {
      return Observable.throw('retry');
    } else {
      return Observable.of(data);
    }
  }).retry().subscribe();

Explanation:

  1. You need to use a flatMap() to transform the items emitted by an Observable into Observables
  2. You need to use Observable.throw() to force an error, in this way the retry() will be invoked
  3. I used a delay(2000), in this way I wait 2 seconds before retrying another call

Upvotes: 3

kemsky
kemsky

Reputation: 15261

Ok, if doWhile is not available, then emulate it with retry:

this.http
  .post(API, postData)
  .map((response: Response) => response.json())
  .do(data => {
       this.saveData(data);
       if(data.length > 0){
           throw new Error();
       }
   })
  .retry()
  .subscribe();

Upvotes: 0

Related Questions