How to use angular observables to retrieve data from API within a repetitive time interval

926 Views Asked by At

I want to understand observables in a practical example. Assume I want to make API calls every 1 minute as long as the APP is on running state. Currently I am doing it using setInterval function as below:

ngOnInit() {

    setInterval(val => this.getDataFromAPI(), 60000)

}

getDataFromAPI() {
    this.dataServices.getDataFromAPI().subscribe((data: any) => {
        this.gaugeData = data;
    },
    error =>{
        console.log('error')
    });
 }

In the dataServices file there is a method 'getDataFromAPIwhich is responsible of making theHTTP` calls.

getDataFromAPI
    return this.http.get(this.base_url + this.endPoint, {
        headers: {
            'tokenid': this.tokenId,
            'accountid': this.accountId'
        }, params: { groupId: groupId, date: '2020-10-05T11:30:00-07:00' }
    })
    .toPromise().then(res => {
        return res;
    });
}

The above example is working very fine, but as mentioned in this article Understanding RxJS Observables and why you need them. they have a different way to create and use observables with subscriptions. How shall create and use observables in the example I provided?

2

There are 2 best solutions below

5
On BEST ANSWER

You could use timer combined with a mergeMap.
You already have this observable:

const apiCall = this.dataServices.getDataFromAPI()

You will have to create an other observable, this will start an observable after 1s and he is gonna emit every 1s:

const myTimer = timer(1000, 1000)

Create an empty subscription in your component, this will give you the ability to unsubscribe later:

sub: Subscription

Now you can make your subscription inside ngOnInit():

ngOnInit() {
  const apiCall = this.dataServices.getDataFromAPI()
  const myTimer = timer(1000, 1000)
  this.sub = myTimer
    .pipe(
      mergeMap( () => this.dataServices.getDataFromAPI() )
    )
    .subscribe( data => this.gaugeData = data )
}

Don't forget to unsubscribe when you are finished, or you will have memory leaks:

ngOnDestroy() {
  this.sub.unsubscribe()
}

I have a demo here if you want to check it out, search for Custom API call in the index.ts

1
On
gaugeData = new BehaviorSubject<any>({});

ngOnInit() {
    setInterval(val => this.getDataFromAPI(), 1000)
}

getDataFromAPI() {
    this.dataServices.getDataFromAPI().toPromise().then((data: any) => {
        this.gaugeData.next(data);
    }).catch(error => {
        console.log('error')
    });
}

First assign gaugeData as an observable then call the api on 1sec interval and then pass new value to gaugeData.