37

I have a function called

opensnack(text) { ... };

which is opening an angular material snackbar with the given text input.

What I want to do is to call this function like every 10 seconds.

How should I do this?

HDJEMAI
  • 9,436
  • 46
  • 67
  • 93
  • 1
    What have you tried so far? – SiddAjmera Oct 05 '18 at 18:27
  • @SiddAjmera https://stackoverflow.com/questions/50585764/angular-6-run-method-is-service-every-10-seconds/50585902 I'm trying these, but couldn't get it to work yet –  Oct 05 '18 at 18:30

5 Answers5

86

Use interval from rxjs

Here's how:

import { interval, Subscription } from 'rxjs';

subscription: Subscription;

...

//emit value in sequence every 10 second
const source = interval(10000);
const text = 'Your Text Here';
this.subscription = source.subscribe(val => this.opensnack(text));

...

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

Alternatively, you can use setInterval which is available as method on the Window Object. So you don't need to import anything to use it.

intervalId = setInterval(this.opensnack(text), 10000);

...

ngOnDestroy() {
  clearInterval(this.intervalId);
}

Here's a SAMPLE STACKBLITZ for your ref.

SiddAjmera
  • 38,129
  • 5
  • 72
  • 110
  • Do I need to import something to use SetTimeout? Because it gives me some errors like this –  Oct 05 '18 at 18:37
  • My bad, that was a typo. I meant `setInterval` Since it is available as an API on the Window Object, you don't really need to import anything to use it. – SiddAjmera Oct 05 '18 at 18:39
  • Maybe I ducked up something, but doesn't seem to work. Can I ask you, to have a look? https://stackblitz.com/edit/angular-enzk8t –  Oct 05 '18 at 18:49
  • Just added a Sample Stackbliz for your ref. Please have a look at it and let me know if that works for you. Please do read the comments carefully though :) – SiddAjmera Oct 05 '18 at 18:51
  • ngOnDestroy is part of OnDestroy interface. Dont forget to implement. – Witold Kaczurba Apr 30 '19 at 18:28
  • There is an error present in the stackblitz. "No overload matches this call. Overload 1 of 2, '(handler: TimerHandler, timeout?: number, ...arguments: any[]): number', gave the following error." – hellmit100 Dec 03 '20 at 12:21
  • 2
    @hellmit100, it will work if you make your callback parameter an arrow function. () => this.addNum() https://stackblitz.com/edit/angular-bgb963?file=src/app/app.component.ts – Don Shrout Feb 04 '21 at 14:12
  • Remember to remove the interval after it's completed as well. If you only unsubscribe the subscription the interval will still keep running every X seconds. I prefer using `takeUntil`, for example: `this. subscription = interval(10000).pipe(takeUntil(this.destroy$)).subscribe(() => { doStuff(); })` and remove it: `ngOnDestroy() { this.destroy$.next(); this.destroy$.complete(); }` where the `this.destroy$` is `Subject`: `private destroy$: Subject = new Subject();` – Calsal Jan 03 '22 at 22:28
  • If I declare source as a Subscription I get "Type 'Observable' is missing the following properties from type 'Subscription': closed, _parentOrParents, _subscriptions, unsubscribe, and 2 more." – Gaspa79 Feb 09 '22 at 12:10
  • @Gaspa79 did you call the `subscribe` method? – SiddAjmera Feb 11 '22 at 00:39
9

You can make use of rxjs library to run a function every X seconds.

import { interval } from 'rxjs';
import { takeWhile } from 'rxjs/operators';

...

 interval(1000)
    .pipe(takeWhile(() => !stop))
    .subscribe(() => {
      // place you code here
    });

The above code snippet will execute the subscribed statements every 1 second, until the stop condition becomes true.

CaptainDaVinci
  • 975
  • 7
  • 23
  • import { interval } from 'rxjs'; import { takeWhile } from 'rxjs/operators'; constructor( ) { this.createNewFutureCostingSNotifier(); } public createNewFutureCostingSNotifier() { console.log('createNewFutureCostingSNotifier()'); interval(1) .pipe(takeWhile(() => false)) .subscribe(() => { console.log('createNewFutureCostingSNotifier() is now working!'); }); } But not working. – Rejwanul Reja Sep 05 '20 at 07:00
  • @RejwanulReja you have set your stop condition to directly to false – bokkie Sep 15 '20 at 08:51
6

Try to use setInterval

setInterval will allow to run a function regularly with the interval between the runs

https://javascript.info/settimeout-setinterval

Example:

function opensnack(text: string) : void {
  console.log(text);
}

setInterval(opensnack, 10000, "my text"); <-- run every 10 second

You can look at this stackblitz example:

HDJEMAI
  • 9,436
  • 46
  • 67
  • 93
1

Angular 6 run a function in every X seconds

import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs';

@Component({
    selector: 'my-app',
    template: `<h2>
      Now {{time | date: 'hh:mm:ss'}}
      
      <hr /> 
      Now {{time$ | async | date: 'hh:mm:ss'}}
    </h2>`
})
export class AppComponent {
  time: Date;
  time$;

  constructor() {
    // First way: manual subscribe
    Observable
      .interval(1000)
      .map(() => new Date())
      .subscribe(res => this.time = res)

    // Angular way: by using the `async` pipe
    this.time$ = Observable.interval(1000).map(() => new Date())
  }
}
Yogesh Waghmare
  • 941
  • 10
  • 10
0
export class AComponent implements OnInit {
  id: string = "1";
  mySub: Subscription;

  constructor(private http: HttpClient) {
    this.mySub = interval(8000).subscribe((func => {
      this.onIdSelect(this.id);
    }))
  }    
  ngOnInit(): void {
  }
  onIdSelect(id) {
    this.http.post('https://jsonplaceholder.typicode.com/posts', id).subscribe((res => {
      console.log(res);
    }))
    // this.mySub.unsubscribe(); 
  }
}

Import the interval and Subscription from rxjs. Here, code is calling the onIdSelect() method every 8seconds. So post response will be printed on the console after every 8seconds. If you want to call the method only once after 8seconds, then just unsubscribe the mySub variable.

Sandeep Kumar
  • 2,397
  • 5
  • 30
  • 37