Home > Back-end >  Angular - Set interval is not working properly inside for loop
Angular - Set interval is not working properly inside for loop

Time:10-01

I want to invoke API with dynamic interval. But when I tried to use below code snippet , it is working but interval time is not working properly.I need to acheive dynamic short polling. Version : Angular 7

ngOnInit() {
    this.liveFunction();
}

liveFunction() {
    var list = [{
        "id": 1,
        "timer": 10000,
        "url": "https://www.sampleurl.com/1"
    },
    {
        "id": 2,
        "timer": 20000,
        "url": "https://www.sampleurl.com/users/1"
    }];
    for (var i = 0, len = list.length; i < len; i  = 1) {
        (function (i) {
            setInterval(function () {
                this.invokeAPI(list[i].url)
            }, list[i].timer)
        })(i);
    }
}

invokeAPI (url) {
    //do stuff 
}

CodePudding user response:

You will have to implement async - await logic for this to work. Try this:

async ngOnInit() {
    await this.liveFunction();
}

async liveFunction() {
    var list = [{
        "id": 1,
        "timer": 10000,
        "url": "https://www.sampleurl.com/1"
    },
    {
        "id": 2,
        "timer": 20000,
        "url": "https://www.sampleurl.com/users/1"
    }];
    for (var i = 0, len = list.length; i < len; i  = 1) {
        (function (i) {
            setInterval(function () {
                this.invokeAPI(list[i].url)
            }, list[i].timer)
        })(i);
    }
}

invokeAPI (url) {
    //do stuff 
}

CodePudding user response:

You lose the scope while using function statements, take a look:

    for (var i = 0, len = list.length; i < len; i  = 1) {
        (function (i) { // "this" keyword now refers to this function, it doesn't have "invokeApi" method
            setInterval(function () { // and here "this" becomes another function without the method you need
                this.invokeAPI(list[i].url)
            }, list[i].timer)
        })(i);
    }

The best solution is to use arrow functions:

      for (var i = 0, len = list.length; i < len; i  = 1) {
          ((i: number) => {
            setInterval(() => {
                this.invokeAPI(list[i].url);
            }, list[i].timer)
          })(i);
      }

Working example: https://stackblitz.com/edit/angular-hvkkas?file=src/app/app.component.ts

Alternatively, you can store "this" in a variable to call the method from different scope:

    const _self = this;
    for (var i = 0, len = list.length; i < len; i  = 1) {
        (function (i) {
            setInterval(function () {
                _self.invokeAPI(list[i].url)
            }, list[i].timer)
        })(i);
    }
  • Related