I have a cross platform app developed using AngularJS and Onsen/Monaca UI.
I have a function that watches for changes on button clicks and if a certain number of clicks have been detected on a button, the user is taken to a confirmation screen.
However, if the user takes too long to select the buttons, they should be re-directed to another screen (not yet defined).
I am trying to implement the $timeout function with this but I cant seem to cancel the $timeout once the user has selected the buttons the right number of times. If the user select the buttons in the allowed time, they are taken to the confirmation page, but then the $timeout message is still displayed after 10 seconds.
Below is my implementation. It can be assumed that everything works - except the $timeout.cancel() in the stop() function.
// Initialise
var timer;
// Watch for changes on button clicks
$scope.$watch('currentAction', function(newValue, oldValue) {
if (counter == 6) {
// User clicked buttons - cancel the timer
stop();
// Segue 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);
}
Where the Segue.goTo() simply segues the user to the passed in page (unrelated 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);
},
}
you are creating timer in $scope.$watch, if the timer is created multiple times and kept with only one variable, you can only cancel the latest one by $timeout(timer). So the solution should be moving $timeout part out of $scope.$watch or keeping timers in an array and loop the array to stop them.
And if you still persist using in $scope.$watch, you shall cancel the previous one before creating new one.
if (timer) {
$timeout.cancel(timer);
}
timer = $timeout(function () {
alert("You are taking too long to respond");
}, 10000);
refer the below code snippet.
timer is created once angular ends render the page.timer will be created once the test 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>