Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Request Async by interval using rxjs in Angular 2

I want to set interval in http request using rxjs. I need to send data on server from n seconds after request finish.

Observable.interval(10000)
                  .?(() => {
                      //request for server. return Observable
                      return this.getData();
                  })
                  .subscribe(() => {
                      console.log("Request done. After 10 second will be next request");
                  });

UPDATE based on .expand() suggested by Mark

ngOnInit() {
  this.getData()
    .expand(() => Rx.Observable.timer(10 * 1000)
      .concatMap(() => this.getData())
    )
    .subscribe(data => {
      console.log('received new data', data);
    });
}

private getData() {
  return Observable.timer(5000)
    .do(() => console.log("timer"));
}
like image 352
Illorian Avatar asked Nov 19 '25 03:11

Illorian


2 Answers

Your usecase is an excellent case for the .expand operator which can recursively execute and return new values. See this snippet in which i have added a lot of timestamp + debug logging to clarify what is going on.

function getData() {
  // simulate remote call which can take some time
  return Rx.Observable.of('')
    .timestamp()
    .do(i => console.log(`[debug] Going to fetch data from server @${i.timestamp}`))
    .map(i => 'the new JSON blob of data to use') // this would be your actual http.get call
    .delay(1500)
    .timestamp()
    .do(i => console.log(`[debug] Data retreived from server @${i.timestamp}`));
}

getData()
  .expand(_ => Rx.Observable.of('') // we need something to delay upon
    .timestamp()
    .do(i => console.log(`[debug] Waiting 1sec for next getData ${i.timestamp}`))
    .delay(1000)
    .concatMap(() => getData())
  )
  .take(5)
  .subscribe(val => console.log(`New data received @${val.timestamp} : ${val.value}`))
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.0.3/Rx.js"></script>

so initially you subscribe to the getData() and expand its value to recursively delay for time before retrieving the next getData(). No subjects are involved in this approach and your subscription stays available for receiving the new values.

like image 96
Mark van Straten Avatar answered Nov 20 '25 17:11

Mark van Straten


i think you want to request server for something every few seconds. can you try this way

make sure you have imported import {Observable} from 'rxjs/Rx' if you don't import it we get observable not found error sometimes

working plnkr http://plnkr.co/edit/vMvnQW?p=preview

import {Component} from '@angular/core';
import {Http} from '@angular/http';
import 'rxjs/Rx';
import {Observable} from 'rxjs/Rx';

@Component({
    selector: 'app',
    template: `
      <b>Angular 2 HTTP request every 5 sec RxJs Observables!</b>
      <ul>
        <li *ngFor="let doctor of doctors">{{doctor.name}}</li>
      </ul>

      `
})

export class MyApp {
  private doctors = [];

  constructor(http: Http) {
    Observable.interval(5000)
    .switchMap(() => http.get('http://jsonplaceholder.typicode.com/users/')).map((data) => data.json())
        .subscribe((data) => {
          this.doctors=data; 
           console.log(data);// see console you get output every 5 sec
        });
  }
}

see google inspect console you will be getting new data every 5 sec

like image 28
Amit kumar Avatar answered Nov 20 '25 16:11

Amit kumar



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!