Stopping an AngularJS timeout from running

I have a multi-platform app created using AngularJS and Onsen/Monaca UI.

In my app, I have a feature that detects button clicks and after a certain number of clicks, the user is directed to a confirmation screen. However, if the user takes too long to make the selections, they should be redirected to another screen (which has not been defined yet).

Although I am trying to use the $timeout function for this purpose, I am facing issues with canceling the timer once the right number of button clicks have been made by the user. Even after progressing to the confirmation page, the $timeout message continues to display after 10 seconds.

Below is the code implementation. It can be assumed that everything works correctly except for the $timeout.cancel() in the stop() function.

// Initialization
var timer;

// Watching for changes on button clicks
$scope.$watch('currentAction', function(newValue, oldValue) {
    if (counter == 6) {
        // User clicked buttons - cancel the timer
        stop();
        // Proceed to next page
        Segue.goTo("confirmation.html");
    }
    else {
        // Start the timer
        timer = $timeout(function () {
            alert("You are taking too long to respond");
        }, 10000);
    }
});

// Cancel the $timeout
function stop() {
    $timeout.cancel(timer);
}

The Segue.goTo() function simply navigates the user to the specified page (not directly related but included for clarity)

var myFunctions = {
    goTo: function (url) {
        var nextPage = url;
        var element = document.querySelector("ons-navigator");
        var scope = angular.element(element).scope();
        scope.myNavigator.pushPage(nextPage);
    },
}

Answer №1

When creating a timer within $scope.$watch, it's important to be mindful of potential issues that may arise if the timer is created multiple times but only one variable is used to keep track of it. In such cases, only the latest timer can be cancelled using $timeout(timer). To address this, consider moving the $timeout section outside of $scope.$watch, or alternatively, store timers in an array and loop through the array to stop them.

If you choose to continue utilizing $scope.$watch, make sure to cancel the previous timer before creating a new one.

if (timer) {
    $timeout.cancel(timer);
}
timer = $timeout(function () {
    alert("You are taking too long to respond");
}, 10000);

Below is a code snippet demonstrating these concepts:

  • The timer is initialized once Angular finishes rendering the page.
  • A new timer will be set when the test variable is changed.

angular.module("app", [])
  .controller("myCtrl", function($scope, $timeout) {
    var timer;
    $scope.$watch('test', function(newValue, oldValue) {
      console.log('$timeout created. value:' + newValue);
      timer = $timeout(function() {
        console.log('$timeout fired. value:' + newValue);
      }, 5000);
    })
    
    $scope.clickEvt = function() {
      console.log('$timeout canceld. currentValue:' + $scope.test);
      $timeout.cancel(timer);
    }
  })
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="myCtrl">
  <input type="text" ng-model="test">
  <button ng-click="clickEvt()">Stop<button>
</div>

Answer №2

consider utilizing this suggestion

$timeout.clear(timer);

just make sure to declare timer variable prior to the if statement

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

Serving files from a Node.js server and allowing users to download them in their browser

I am facing an issue with my file repository. When I access it through the browser, the file automatically downloads, which is fine. However, I want to make a request to my server and then serve the file result in the browser. Below is an example of the GE ...

Ways to send information from Vue instance to nested components

Currently, I am fetching data using AJAX from the Vue instance and trying to pass it onto different components. As I delve deeper into learning Vue.js, I can't help but notice that the documentation seems a bit scattered... This snippet showcases wha ...

Arranging the placement of ui-angular carousel navigation buttons

I am currently working on a carousel that showcases images along with some meta data. For medium and large screens, I want the meta data to be displayed on the right side of the image, while for smaller screens, I need it to appear below the image. So far, ...

Trouble displaying image due to issues with javascript, html, Angular, and the IMDb API integration

I have been working on displaying images from the IMDb API in my project. Everything works perfectly fine when I test it locally, but once I deploy the project to a server, the images do not load initially. Strangely, if I open the same image in a new tab ...

Creating an array of JSX elements or HTMLElements in a React TypeScript rendering

Currently in the process of developing a custom bootstrap card wrapper that allows for dynamic rendering of elements on the front and back of the card based on requirements. Here is the initial implementation: import React, { useState, ReactElement } from ...

Non-IIFE Modules

Check out this discussion on Data dependency in module I have several modules in my application that rely on data retrieved from the server. Instead of implementing them as Immediately Invoked Function Expressions (IIFEs) like traditional module patterns ...

Share user group Node Express with relevant data

I am looking for a way to create and send a customized navigation object to be rendered in an Express application based on user groups. My current approach involves adding middleware to each route: var navMiddleware = function() { return function(req, ...

What is the best way to toggle dropdown menu items using jQuery?

Upon clicking on an li, the dropdown menu associated with it slides down. If another adjacent li is clicked, its drop down menu will slide down while the previous one slides back up. However, if I click on the same li to open and close it, the drop down m ...

Tips for coordinating the execution of 2 async.waterfalls in Node.js

I have a series of read commands that need to be executed in sequence. If any of them fail, the processing stops. The array readCommands contains functions for reading... async.waterfall(readCommands, function(err) { if (err) { console.log(e ...

Fade in an image using Javascript when a specific value is reached

Here's the select option I'm working with: <div class="okreci_select"> <select onchange="changeImage(this)" id="selectid"> <option value="samsung">Samsung</option> <option value="apple">App ...

Interacting between Angular controllers and services to efficiently showcase JSON information

Recently, I started working with Angular 1.5+ and I'm facing some challenges with the basics, particularly when it comes to displaying data from a JSON file on the DOM. Although I can fetch the data successfully (at least I think so, as it console lo ...

AngularJS routing is disrupted by html5mode

Encountering a unique issue while using html5Mode with ngRoute. Here is the relevant snippet of code: (function () { var config = function ($routeProvider, $locationProvider) { $routeProvider .when('/', { templateUrl: 'h ...

Having trouble with blurriness in the SVG image loading on three.js

Currently, I am using loadTexture (THREE.ImageUtils.loadTexture('/images/areaYellow.svg')) to load SVG images. However, when I zoom in on the image, it becomes blurred. Is there a way to load the image without this blurriness? I am currently work ...

Infinite scroll causing Firebase ".length" function malfunction

My NextJs website is encountering errors related to Firebase infinite scroll. The issue seems to be with the .length property being undefined for some unknown reason. I am struggling to debug the code and make it work properly in Next.js. Any help would be ...

webdriverIO encountered an unhandled promise rejection, resulting in a NoSuchSessionError with the message "invalid session id

I am currently learning how to conduct UI testing using Jasmine and WebdriverIO in conjunction with NodeJS. Below is a snippet of my test code: const projectsPage = require('../../lib/pages/projects.page'); const by = require('selenium-we ...

What steps should be taken to validate a condition prior to launching a NextJS application?

In my NextJS project (version 13.2.4), I usually start the app by running: npm run dev But there's a new requirement where I need to check for a specific condition before starting the app. If this condition is not met, the app should exit. The condi ...

Leverage the output from one $http request in AngularJS to make another $http request

My goal is to use $http to fetch data (such as students), then make another $http call to retrieve studentDetails. Next, I want to add a portion of studentDetails to the students JSON. The tricky part is that I need the response from the first call to cre ...

Switching the visibility of rows in a table

Imagine this as my example table: <table> <tr> <td>a</td> <td>one</td> <td>two</td> </tr> <tr> <td>b</td> <td>three</td> <td>four</t ...

Switch color in Material-UI based on props

Utilizing code inspired by the Material-UI documentation on customizing the switch, you can customize the switch color to be blue: import React from 'react' import Switch from '@material-ui/core/Switch' import {withStyles} from '@ ...

Tips on resolving JavaScript's failure to adjust to the latest HTML inputs

I'm working on a homepage where users can choose their preferred search engine. The issue I'm facing is that even if they switch between search engines, the result remains the same. I've experimented with if-then statements, but the selecti ...