AngularJS: How do I stop the $interval from running indefinitely?

After spending hours reading the documentation, it's now 3am and I'm at my wit's end. Below is my controller code:

controller('makeDashCtrl', function ($scope, $rootScope, $cookies, $location, $http, $interval) {

    var userId  = $cookies.get('user_id');
    var orgId   = $cookies.get('org_id');

    $http.get('/api/consolidateProfile/').then(function(data){
      console.log(data);
    }, function(res){
      console.log(res + " - Eh, consolidateProfile probably timed out, no biggie")
    })


    var testStart = $interval(function(){
      $http.get('/api/testProgress/' + userId).then(function(obj){

        $scope.message = obj.data.message;
        $scope.sub = obj.data.sub;

        if(obj.data.nextPhase){
          console.log("Should be cancelling...");
          nextScrape();
          $interval.cancel(testStart);  // This one cancels fine
        }
      }, function(err){
        $interval.cancel(testStart);  
      });  
    }, 1000);

    function nextScrape(){

       console.log("In checkScraperadsfsdfads!")
      var checkScraper = $interval(function(){
        console.log("In checkScraper REAL!")
        $http.get('/api/checkScraper/' + userId).then(function(obj){
          var msg = JSON.parse(obj.data);
          console.log("Got some data!")
          console.log(obj);
          if(msg.doneFbs){
            $scope.fbMsg = "We've finished gathering " + msg.doneFbs + " Facebook accounts";
          }

          if(msg.doneTwits){
            $scope.twitMsg = "We've finished gathering " + msg.doneTwits + " Twitter accounts";
          }

          $scope.message = msg.message;
          $scope.sub = msg.sub;


          if(msg.finished){
            $interval.cancel(checkScraper); // This does NOT cancel
            console.log("Scraping Done!")
            $location.path('/dashboard') 
          }


        },function(err){
          console.log("There was an error in Checkscraper ")
          console.log(err)
          $interval.cancel(checkScraper);  // This does NOT cancel when there's an error
        });  
      }, 3000)
    }
  })

I've added comments in the above code for reference. Despite transitioning to the next page using $location.path(), the interval within the nextScrape() function continues running. What am I missing here?

Answer №1

If your API call takes longer than a second to return, it's possible that you could have multiple AJAX requests running simultaneously. Instead of relying on the $interval function, consider making one initial call and using $timeout to schedule a subsequent call only when necessary after the first call completes.

function checkProgress() {
  $http.get('/api/testProgress/' + userId).then(function(obj){
    $scope.message = obj.data.message;
    $scope.sub = obj.data.sub;

    if(obj.data.nextPhase){
      // move on to next phase
      nextScrape();
    } else {
      // not done, schedule another check
      $timeout(checkProgress, 1000);
    }
  }, function(err){
    // error handling - cancel request or schedule another progress check
  });  
}

Answer №2

It seems like the code is sending multiple requests before receiving a response from the Ajax call. This indicates that your ajax request is taking more than a second to return a response. The reason behind this could be that you have set a very short time interval for fetching data from the server.

To stop the $interval after redirecting to another page, you can utilize the $destroy event on the scope. It's important to manually clear events because they will not disappear on their own. You can stop the interval when leaving the page by destroying the event on scope.

Sample Code:

$scope.$on('$destroy', function(){
   $interval.cancel(testStart);
})

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

Guide on choosing a specific div element from a different page using AJAX

I have a Social Media platform with posts, and I am trying to display the newest ones using JavaScript (JS) and AJAX. I attempted to reload my page using AJAX and insert it into a div element, but now the entire website is loading within that div element, ...

Incorporating React into an already existing webpage and accessing URL parameters within a .js file

Following the official guidelines: To include React in a website, visit https://reactjs.org/docs/add-react-to-a-website.html I have created a file named test.html with the following content: <!DOCTYPE html> <html> <head> < ...

using ng-class or ng-style for displaying error messages when validating a text area content

I'm curious about the most effective "angular" method for changing the character count style for validation purposes. I have a text area with a 250-character limit. Instead of restricting users to exactly 250 characters, we want to allow them to excee ...

Begin a fresh page within a separate window, proceed to print the contents, and subsequently close the window

I am facing some difficulties with this code. I am attempting to use the "onClick" function to change the image once it is clicked, open a new page in a new window, print the newly opened window, and then close it. The issue I am encountering is that while ...

I am interested in modifying the directive's template value

To create a custom directive, I start by writing the following code: module.directive("display", function(content){ var info = content.getContent(); return{ scope:{}, restrict:"AE", template: info, } }); In order to manage the content being d ...

Guide on integrating jQuery list filtering in Ionic 2

I stumbled upon a jQuery function that filters data in HTML, found it online. Now, I want to incorporate a similar feature into my Ionic app. However, I am unsure about the modifications required in list-search-min.js. Here is a snippet of my index.html: ...

Issue with source file detection in RequireJS and Karma

Having trouble testing my Angular scripts with Karma and RequireJS, as I keep encountering this error: Error in Firefox 28.0.0 (Mac OS X 10.9): 'There is no timestamp for /base/app/public/js/test/unit/controllersSpec.js!' Warning [web-server]: ...

Show a modal when the axios request is finished

EDIT: After some exploration, I've shared the solution I found in case it helps others facing a similar issue. I'm currently working on building a reusable Bootstrap 5 modal child component within Vue3. The goal is to pass an ID as a prop from t ...

Iterate through an array and update the innerHTML content for each value contained in the array

Looking to replace a specific word that keeps appearing on my website, I experimented with various functions and stumbled upon this method that seems to work: document.getElementsByClassName("label")[0].innerHTML = document.getElementsByClassName ...

Unresolved promise: Internal server issue

I encountered an exception while working on my Nativescript app. EXCEPTION: Uncaught (in promise): Server error JS: ORIGINAL STACKTRACE: JS: Error: Uncaught (in promise): Server error JS: at resolvePromise (/data/data/com.yourdomain.appname/files/app/ ...

Save an array of messages by making separate API calls for each one

I have a function that makes an API call to retrieve a list of message IDs. Here is the code: function getMessageList(auth) { api.users.messages.list({ auth: auth, userId: 'me', }, function(err, response) { if (er ...

What are the best practices for sharing context in express and typescript?

Implementing a solution to expose a value to all request handlers using express and typescript is my goal. I am looking for a way to easily "inject" this value from a middleware or an alternative method that allows for simple mocking if needed. Here is th ...

What is the best way to eliminate the additional slash from an optional parameter at the first level in a URL

Is it possible to make the first parameter optional for the login state? Below is the .state definition that I am using: $stateProvider .state("login", { url: '/:team/login/', templateUrl: 'app/user/login.html', ...

When executing store.sync() in ExtJS, all fields are passed

In the latest version of ExtJS (6.5.0), I have set up a Store and an editable grid panel: Ext.define('StateStore',{ extend: 'Ext.data.Store', alias: 'store.stateStore', storeId : 'StateStore', field ...

Developing a Multi-Faceted Array Utilizing SQL Data

The requirement of the plugin I am using is to provide it with an array structure in JavaScript that looks like this: var data = [ { "id": 1, "name": "University1", "list": [ {"id": 1, "name": "Dorms", "list": ...

After the rendering process, the React Component member goes back to a state of

One issue I encountered is related to a component that utilizes a separate client for making HTTP requests. Specifically, when trying to use the client within a click event handler, the call to this.client.getChannel() fails due to this.client being undefi ...

AngularJS Dilemma: Virtual Machine Data Set but No Rendering in Sight

Below is the AngularJS controller code written in Typescript: /// <reference path='../../definitions.d.ts' /> module baseApp.viewControls.products { export interface IProductsScope extends IAppScope { vm: { product ...

Set a variable for a module dependency within an AngularJS application

Can someone help me with setting a value for a dependent module in my app? Here is the code snippet I have: var myapp = angular.module('myapp',['mymodule']); I am trying to set a value like this: mymodule.value('value',&apo ...

Using Angular JS to apply filters conditionally

Average Product and Channel Price: {{average_price | currency}} The average price is represented as a string with an initial value of 'None', which cannot be 0.0. Initially, the value 'None' is not displayed when applying the currency ...

Is comparing strings in JavaScript as efficient as comparing numbers?

Considering creating a JavaScript enum library involves deciding how to store the values, I'm at a crossroads. Should I opt for speed in comparison or prioritize readability during debugging by using strings or numbers? While objects are an option too ...