Issue with setInterval function execution within an Angular for loop

My goal is to dynamically invoke an API at specific intervals. However, when attempting to utilize the following code snippet in Angular 7, I encountered issues with the interval timing. I am seeking a solution for achieving dynamic short polling.

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 
}

Answer №1

To make this function properly, you will need to incorporate async/await functionality. Here's an example of how you can do it:

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

async liveFunction() {
    var requests = [{
        "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 = requests.length; i < len; i += 1) {
        (function (i) {
            setInterval(function () {
                this.invokeAPI(requests[i].url)
            }, requests[i].timer)
        })(i);
    }
}

invokeAPI(url) {
    // Perform API request
}

Answer №2

When using function statements, the scope can be lost as shown below:

    for (var i = 0, len = list.length; i < len; i += 1) {
        (function (i) { // This function has a different scope, missing the "invokeAPI" method
            setInterval(function () { // Another function scope without the needed method
                this.invokeAPI(list[i].url)
            }, list[i].timer)
        })(i);
    }

One way to resolve this issue is by using 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);
      }

See a working example here: https://stackblitz.com/edit/angular-hvkkas?file=src/app/app.component.ts

Alternatively, you can store "this" in a variable to access the method from a 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);
    }

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for keeping a div element at the top of the page

I am looking to have a div stick to the top of the page when someone scrolls down When the page is scrolled, the green div with class stickdiv should automatically stick to the top var left = document.getElementsByClassName("stickdiv"); for( var i = 0; ...

Continuous loop of Vue countdown timer

Hey there! I'm currently working on implementing a countdown timer, but I keep encountering a console error that says 'You may have an infinite update loop in a component render function.' It seems like something needs to be adjusted. expor ...

organizing strings in alphabetical order using TypeScript

My md-collection is set up to display a list of emails like this: <md-collection-item repeat.for="u of user" class="accent-text"> <div class="row"> <di ...

No routes found to match. URL Segment: ''. This issue occurs when attempting to utilize child routes with Angular 2

I am having issues with this specific plunker that seems to not be working correctly. To try and fix the problem, I attempted to comment out a section of code... RouterModule.forRoot([ { path: "", component: TestComponent, ...

Despite the onsubmit returning false, the submit operation still goes through

I seem to have hit a roadblock yet again. My registration form incorporates three JavaScript functions which display the desired output when triggered by an onchange event within my HTML form. These functions generate a Bootstrap alert while the user is co ...

Alert: Angular has detected that the entry point '@libray-package' includes deep imports into 'module/file'

Recently updated the project to Angular 9.1 and now encountering multiple warnings from the CLI regarding various libraries, such as these: Warning: The entry point '@azure/msal-angular' includes deep imports into 'node_modules/msal/lib-com ...

Setting up the customized filename for precompiled Handlebars templates

When compiling Handlebars templates with the NPM package, is there a way to manually adjust the name/index that is generated? In my experience using Handlebars in various environments like Rails, NodeJS, and PHP, I've observed that the generated temp ...

The Angular parent component is able to detect changes in the ng-content child component

I am looking for a way to have a function execute in my parent component when an event is emitted from my child component. The child component is inserted into the parent using ng-content. I have simplified the code but I am struggling to get the child com ...

Issues have been identified with the capabilities of Vue's Mutations and Actions

My Index.js from the Store Folder import Vue from "vue"; import Vuex from "vuex"; import state from "../store/state"; import mutations from "../store/mutations"; import actions from "../store/actions"; Vu ...

Version 13 of the Discord slash command encounters an "interaction failed" error

After implementing the slash commands in Discord v13 as per the instructions on discordjs.guide, I encountered an issue when trying to use the commands - interaction failed. Here is a snippet of my code: // Here goes the code const { Client, Collection, ...

Traverse through an array of objects with unspecified length and undefined key names

Consider the following object arrays: 1. [{id:'1', code:'somecode', desc:'this is the description'}, {...}, {...}] 2. [{fname:'name', lname:'last name', address:'my address', email:'<a h ...

fresh map from Google: Coordinates LatLng may not be a number, but my hunch tells me it is

Seeking Assistance with this Issue - For example, the initial location data appears as: "Object Lat: -36.768498 Lng: 174.75895" However, an error is indicating that the latitude is not recognized as a number. Rather than making adjustments without clea ...

An issue occurred: the channel has been terminated within the ChildProcess.target.send function at internal/child_process.js, line 562, character

My Angular 5 application is giving me an error message that says "ERROR in Error: channel closed". This occurs after running the application. The issue seems to persist even though it works fine for a few minutes after executing ng serve. Has anyone else e ...

Create a sleek transition for your Bootstrap 4 fixed Navbar by having it smoothly slide down and change to a

Throughout my experience with HTML/CSS, I have predominantly relied on themes that included this feature by default. However, as I now venture into building from scratch, I find myself struggling to recreate it. You'll notice that I have a stylish fi ...

The $or operator in mongoose falls short in providing complete data when paired with the find() method

I am currently utilizing the find method in conjunction with the $or operator to search the database for any duplicate data within this specific line. const duplicate = await NewItemsData.find({ $or: newItems }); Upon inspecting the variable in the consol ...

Preserve the timestamp of when the radio query was chosen

I'm interested in finding a way to save the user's selected answer for a radio button question and track the time they saved it. Is there a way to achieve this using HTML alone? Or would I need to utilize another coding language or package? Just ...

Conceal the block quotes while substituting with a newline

My HTML page contains numerous comments enclosed in blockquotes. I attempted to implement a feature that allows users to hide all the comments with just one click by using the following JavaScript code: const blockQuotes = document.getElementsByTagName(& ...

Looping through a JSON array and encoding it using the `

I am looking to retrieve data from the database using AJAX and populate a 'select' tag with that data. Each name should be displayed in its own 'option'. Here is the code snippet: Index.php: <label>Select:</label> <sel ...

Tips for sorting the mat table dataSource by inputting two columns and selecting the search button

I am currently displaying mat table data with columns for Role, Status, Email ID, and Name. Above the table, there is a search area where users can enter values for Role and Status and then click the Search button. If the entered values match exactly for ...

Modifying Selectize Ajax data in real-time

How can the student_id be changed each time the modal is opened? This is the code: $('#relationshipModal input[name=existing_user]').selectize({ valueField: 'id', searchField: 'name', options: [], create: fal ...