I am making a demo in which I am fetching data from the server after regular intervals of time using $interval Now I need to stop/cancel this.
How I can achieve this? If I need to restart the process, how should I do that?
Secondly, I have one more question: I am fetching data from the server after reqular intervals of time. Is there any need to use $scope.apply or $scope.watch?
Here is my plunker:
app.controller('departureContrl',function($scope,test, $interval){
setData();
$interval(setData, 1000*30);
function setData(){
$scope.loading=true;
test.stationDashBoard(function(data){
console.log(data);
$scope.data=data.data;
$scope.loading=false;
//alert(data);
},function(error){
alert('error')
}) ;
}
});
http://plnkr.co/edit/ly43m5?p=preview
You can store the promise returned by the interval and use $interval.cancel() to that promise, which cancels the interval of that promise. To delegate the starting and stopping of the interval, you can create start() and stop() functions whenever you want to stop and start them again from a specific event. I have created a snippet below showing the basics of starting and stopping an interval, by implementing it in view through the use of events (e.g. ng-click) and in the controller.
angular.module('app', [])
.controller('ItemController', function($scope, $interval) {
// store the interval promise in this variable
var promise;
// simulated items array
$scope.items = [];
// starts the interval
$scope.start = function() {
// stops any running interval to avoid two intervals running at the same time
$scope.stop();
// store the interval promise
promise = $interval(setRandomizedCollection, 1000);
};
// stops the interval
$scope.stop = function() {
$interval.cancel(promise);
};
// starting the interval by default
$scope.start();
// stops the interval when the scope is destroyed,
// this usually happens when a route is changed and
// the ItemsController $scope gets destroyed. The
// destruction of the ItemsController scope does not
// guarantee the stopping of any intervals, you must
// be responsible for stopping it when the scope is
// is destroyed.
$scope.$on('$destroy', function() {
$scope.stop();
});
function setRandomizedCollection() {
// items to randomize 1 - 11
var randomItems = parseInt(Math.random() * 10 + 1);
// empties the items array
$scope.items.length = 0;
// loop through random N times
while(randomItems--) {
// push random number from 1 - 10000 to $scope.items
$scope.items.push(parseInt(Math.random() * 10000 + 1));
}
}
});
<div ng-app="app" ng-controller="ItemController">
<!-- Event trigger to start the interval -->
<button type="button" ng-click="start()">Start Interval</button>
<!-- Event trigger to stop the interval -->
<button type="button" ng-click="stop()">Stop Interval</button>
<!-- display all the random items -->
<ul>
<li ng-repeat="item in items track by $index" ng-bind="item"></li>
</ul>
<!-- end of display -->
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
var interval = $interval(function() {
console.log('say hello');
}, 1000);
$interval.cancel(interval);
var promise = $interval(function(){
if($location.path() == '/landing'){
$rootScope.$emit('testData',"test");
$interval.cancel(promise);
}
},2000);
When you want to create interval store promise to variable:
var p = $interval(function() { ... },1000);
And when you want to stop / clear the interval simply use:
$interval.cancel(p);
$scope.toggleRightDelayed = function(){
var myInterval = $interval(function(){
$scope.toggleRight();
},1000,1)
.then(function(){
$interval.cancel(myInterval);
});
};
Related
Hi am new to Angular am using $interval to call a function periodically and i want to display a timer in the screen when the next function call will happen , a countdown to the next call . is there anyway simple way to do within this function .
function init(){
$scope.interval = $interval(function(){
$scope.loading = true;
//$scope.countdown = countdown to next call;
doSomework();
}, 60000);
}
Any suggestions are welcome .Thanks in advance
function init(){
var remainingTime = 60;
var interval = $interval(function(){
$scope.loading = true;
remainingTime = remainingTime - 1;
$scope.showRemainingTIme = remainingTime; // Use this variable to show on the view page
if(remainingTime == 0) {
$interval.cancel(interval);
doSomework();
}
}, 1000);
}
Here is what you need. The second argument in $interval is the time after which you want the function to execute and its in miliseconds so 1000ms=1sec.
So after every second it will reduce thhe value of $scope.remainingTimeby 1. You can have the value according to your requirement. Just for demo i have considered it to be 60 and the interval to be 1sec so after every second the $scope.remainingTimewill be decremented by 1
angular.module('timerApp', []);
angular.module('timerApp').controller('timerController', ['$scope', '$interval', function ($scope, $interval) {
$scope.remainingTime = 60;
$scope.timeInterval=$interval(function(){
$scope.remainingTime = $scope.remainingTime - 1;
if($scope.remainingTime==0){
//$interval.cancel($scope.timeInterval);
$scope.remainingTime=60;
}
}, 1000);
}]);
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
</head>
<body>
<div ng-app="timerApp" ng-controller="timerController">
<div >{{remainingTime}}</div>
</div>
</body>
I have this fiddle : https://jsfiddle.net/reko91/stfnzoo4/
Im currently using Javascripts setInterval() to log a string to console.
What I want to do, is in this setInterval function check whether the interval variable has changed, if it has, change the interval in the setInterval function. I can lower the interval variable by 100 (speeding the function up) by a click a button.
Is this possible ?
Someone mentioned this : Changing the interval of SetInterval while it's running
But this is using a counter, so they only run it a certain amount of times. I need to run it for however long, but change how fast the function gets called again.
Here is the code :
var interval = 2000;
setInterval(function() {
interval = getInterval();
console.log('interval')
}, interval);
function getInterval() {
return interval;
}
$('#speedUp').on('click', function() {
interval -= 100;
console.log(interval)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id='speedUp'>
speed up
</button>
I would just stop the interval and start a new one with the different timing
var interval = 2000;
var intervalId;
// store in a function so we can call it again
function startInterval(_interval) {
// Store the id of the interval so we can clear it later
intervalId = setInterval(function() {
console.log(_interval);
}, _interval);
}
function getInterval() {
return interval;
}
$('#speedUp').on('click', function() {
interval -= 100;
// clear the existing interval
clearInterval(intervalId);
// just start a new one
startInterval(interval);
console.log(interval)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id='speedUp'>
speed up
</button>
When I click the mic icon two times simultaneously it comes back to inactive state but the timeout function still takes place.
Below are my console values :
true
false
false
Instead of:
true
false
How to prevent this from happening.
// Start listening on click.
var active= false;
var $mic = $("#mic-container");
$mic.click(function(event){
//event.preventDefault();
// if we're recording when the button is clicked
if(active) {
$mic.removeClass("active pulse");
active=false; console.log(active);
annyang.abort();
// if we're not recording when the button is clicked
} else {
annyang.start({ autoRestart: false, continuous: false }); // start listening
active = true; console.log(active); // set recording var to true
$mic.addClass('active pulse'); // turn on active class
setTimeout(function(){
$mic.removeClass("active pulse");
active=false; console.log(active);
annyang.abort();
}, 8000);
}
});
annyang.addCallback('resultNoMatch', function () {
$('.myErrorText').html('Try saying a valid command. See help section for a list of valid commands!');
$mic.addClass("result-no-match");
setTimeout(function(){
$mic.removeClass("active pulse result-no-match");
active=false; console.log(active);
annyang.abort();
}, 500);
});
annyang.addCallback('resultMatch', function () {
$('.myErrorText').text('');
$mic.addClass("result-match");
setTimeout(function(){
$mic.removeClass("active pulse result-match");
active=false; console.log(active);
annyang.abort();
}, 500);
});
Even i had the same kind of problem. Try this
// Start listening on click.
var timeoutHandle;
var active= false;
var $mic = $("#mic-container");
$mic.click(function(event){
//event.preventDefault();
if(active)
annyang.abort();
else
annyang.start({ autoRestart: false, continuous: false});
});
annyang.addCallback('start', function () {
active = true; console.log(active);
$mic.addClass('active pulse');
window.clearTimeout(timeoutHandle);
timeoutHandle = setTimeout(annyang.abort, 5000);
});
annyang.addCallback('end', function () {
window.clearTimeout(timeoutHandle);
timeoutHandle = setTimeout(function () {$mic.removeClass("active pulse result-match result-no-match");}, 200);
active=false; console.log(active);
});
annyang.addCallback('resultNoMatch', function () {
$mic.addClass("result-no-match");
$('.myErrorText').html('Try saying a valid command. See help section for a list of valid commands!');
});
annyang.addCallback('resultMatch', function () {
$('.myErrorText').text('');
$mic.addClass("result-match");
});
Assign the timeout to a variable and then just call the clearTimeout() method when you want to kill the timer. For example:
var resultMatchTimer = null;
// stops the timer
if(resultMatchTimer) {
clearTimeout(resultMatchTimer);
resultMatchTimer = null;
}
// starts the timer
resultMatchTimer = setTimeout(..., ...);
You should store the result (handle) of setTimeout in a var and call clearTimeout on that handle.
var timeoutHandle = setTimeout(...);
clearTimeout(timeoutHandle); // this will clear the timeout.
With the correct scoping, you can call clearTimeout from all your clicks, and decide you need 3 handles to clear them individually or just use one form all setTimeouts and just clear it. When een new setTimeout is called your handle will be overwritten so make sure your clear the other timeout before that.
The problem is that timeouts are being started while those from previous clicks are still counting.
You're going to have to keep track of the active timeouts, and cancel them if they're running while the user clicks again.
This is possible because setTimeout returns an identifier you can pass to clearTimeout to, as the function name suggests, cancel the timeout.
For example:
var resultMatchTimeout; // Variable to store a reference to a timeout in.
annyang.addCallback('resultMatch', function () {
$('.myErrorText').text('');
$mic.addClass("result-match");
if(resultMatchTimeout){ // If a timeout is running, cancel it.
clearTimeout(resultMatchTimeout);
resultMatchTimeout = null;
}
resultMatchTimeout = setTimeout(function(){ // Save a reference to the current timeout.
$mic.removeClass("active pulse result-match");
active=false; console.log(active);
annyang.abort();
}, 500);
});
You're going to have to do this for your other setTimeout calls too, obviously.
Just make sure to use different variables for each of the timeouts, otherwise, you 'll be cancelling the wrong timout.
One more thing to consider: set the active/not-active state based on the actual voice recognition engine state and not based on user clicks.
Check annyang.isListening()
Every setTimeout() returns a unique Id which could be used to clear the timeout using clearTimeout.
I can see that you have multiple timers running, so what you could do is store all the ids returned each time from setTimeout method in a array and use the same array to clear all the timers in a loop.
MDN reference: https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout
JS CODE:
var myVar;
function myFunction() {
myVar = setTimeout(function(){ alert("Hello"); }, 3000);
}
function myStopFunction() {
clearTimeout(myVar);
}
Note: This is just a generic solution, which can be a base for final/actual solution
I'm have a timer that polls a server for data every 10 seconds. However, everytime a user switches to another controller, the timer should get destroyed. For some reason it's not happening with my code below. The timer keeps polling the server regardless if I change controllers.
controller.js
$scope.init = function() {
//timer and timer stoper
$scope.counter= 0;
var mytimeout = $timeout($scope.onTimeout, 10000);
$scope.$on('$locationChangeStart', function() {
$timeout.cancel(mytimeout);
});
};
$scope.onTimeout = function() {
//polling server function
$scope.counter++;
var mytimeout = $timeout($scope.onTimeout, 10000);
var increase = 0;
inboxServ.check_newusers().then(function(data) {
if (data == "true") {
$scope.retrieveusers(increase);
}
});
};
It seems like you have a scope issue. You have $scope.init() which creates a timeout (held by mytimeout) and also wires up logic to cancel it if you start to change location. However, the function executed (onTimeout) starts another timeout, but assigns it to a different locally scoped mytimeout.
I would expect it, as is, to cancel the first timeout if you change location within the first 10 seconds, and fail to do so any time after that because the variables are different.
It might be as simple as changing it to something like this:
$scope.init = function() {
//timer and timer stoper
$scope.counter= 0;
$scope.mytimeout = $timeout($scope.onTimeout, 10000);
$scope.$on('$locationChangeStart', function() {
$timeout.cancel($scope.mytimeout);
});
};
$scope.onTimeout = function() {
//polling server function
$scope.counter++;
$scope.mytimeout = $timeout($scope.onTimeout, 10000);
var increase = 0;
inboxServ.check_newusers().then(function(data) {
if (data == "true") {
$scope.retrieveusers(increase);
}
});
};
Currently i am using angular js
I have one get method to get data from server side in default.html page
function bindActiveLoans() {
$http.get(rootUrlSingleEscaped + '/cooperativa/allunfundedloans/?authId=' + userInfo.UserId)
.success(function (response) {
if (response.Loans.length == 0) {
$scope.IsValues = false;
$scope.$apply();
return true;
}
$scope.IsValues = true;
$scope.unfundedLoans = response;
});
};
setInterval(function () {
$scope.$apply(bindActiveLoans());
}, 5000);
The above function helps to get the data from server side method in every 5 seconds.
Here, I have an issue.
Additionally I have some more pages, like
default2.html,default3.html,default4.html,default5.html.
The timer is still running while i navigation default.html page to default1.html page. I want to only that timer running in default.html page.If i go to another page,then the timer should stop. How can we achieve it?
From the angularjs example in the $interval API page.
var interval = $interval(function() {
console.log('say hello');
}, 1000);
$interval.cancel(interval);
With $interval.cancel(var) you can stop the interval and if you want to stop it when navigating to another page you should try something like this.
var interval = null;
module.controller('SomeController', '$interval', function($interval) {
interval = $interval(function() {
...
}, 2000);
}).run(['$rootScope', '$interval', function($rootScope, $interval) {
$rootScope.$on('$routeChangeStart', function() {
$interval.cancel(interval);
});
}]);
You can listen to the $routeChangeStart event and do the clearing of the interval depending on the route parameters,
$scope.$on('$routeChangeStart', function (scope, next, current) {
if(<next is not default.aspx>){
// clear interval here
}
});
call clearInterval function when navigating from default page
e.g.
var myVar = setInterval(function () {
$scope.$apply(bindActiveLoans());
}, 5000);
function myStopFunction()
{
clearInterval(myVar);
}
Call myStopFunction