Angular 6 - run method in service every 10 seconds

50,493

Solution 1

Use rxjs timer to call the api request at startup and then every 10s.

This is best achieved by using rxjs to divide and conquer.

Firstly, import the following:

import { timer, Observable, Subject } from 'rxjs';
import { switchMap, takeUntil, catchError } from 'rxjs/operators';

Then add the property to handle request to the api:

private fetchData$: Observable<string> = this.myservice.checkdata();

Next, add the property to handle the timing:

private refreshInterval$: Observable<string> = timer(0, 1000)
.pipe(
  // This kills the request if the user closes the component 
  takeUntil(this.killTrigger),
  // switchMap cancels the last request, if no response have been received since last tick
  switchMap(() => this.fetchData$),
  // catchError handles http throws 
  catchError(error => of('Error'))
);

At last, fire the kill command if the component is killed:

ngOnDestroy(){
  this.killTrigger.next();
}

Here is a StackBlitz Demo.

Solution 2

Try with timer from RxJS :

import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subscription, timer } from 'rxjs';
import { switchMap } from 'rxjs/operators';

import { MyService } from 'path/to/the/service/my-service.service';

@Component({
  ......
})
export class MyExampleComponent implements OnInit, OnDestroy {
    subscription: Subscription;
    statusText: string;
    
    constructor(private myService: MyService) {}

    ngOnInit() {
        this.subscription = timer(0, 10000).pipe(
          switchMap(() => this.myService.checkdata())
        ).subscribe(result => this.statusText = result);
    }

    ngOnDestroy() {
        this.subscription.unsubscribe();
    }
}

interval(10000) from RxJS is not appropriate, because it will start to emit values ONLY after 10sec and not immediatly for the first time (and I think that's not what you're looking for).

However, timer(0, 10000), will emit values immediatly (0) and every 10sec (10000) until unsubscription.

Solution 3

The rxjs way to do this would be the following.

import { interval } from 'rxjs/observable/interval';
import { map } from 'rxjs/operators';

const timeInterval$ = interval(10000);

timeInterval$.pipe(
  map( () => this.http.get(//some url);
);

Solution 4

In your checkData method you could do something like this:

import { timer, of } from 'rxjs';
import { switchMap, catchError } from 'rxjs/operators';

checkData() {
    return timer(0, 10000)
        .pipe(
           switchMap(_ => this.http.get('my url')),
           catchError(error => of(`Bad request: ${error}`))
        );
}

Then your subscribe will get the result of the http call every 10 seconds.

Share:
50,493
Admin
Author by

Admin

Updated on July 09, 2022

Comments

  • Admin
    Admin almost 2 years

    I have this service using HttpClient to get some data :

    checkData() {
        return this.http.get('my url');
    }
    

    The on the footer component I call it and display the result :

    ngOnInit() {
        this.myservice.checkdata().subscribe( result => { this.statustext = result } );
    }
    

    This works, but I need this method to be run every 10 seconds so it's up to date.

    How can I do this?