How to call function every 10 seconds? $timeout and setTimeout calling the function dataTime only one time, I would like repeating this constantly with no end.
angular
.module('sfcLeftSiteBar')
.component('leftSiteBar', {
templateUrl: '/Panel/LeftSiteBar/Templates/_leftSiteBar.html',
controller: ['$http', '$window', '$state', '$scope', '$timeout', function ($http, $window, $state, $scope, $timeout) {
function dataTime() {
$http.post('/LeftSiteBar/TimeProvider').then(function (result) {
console.log("czas" + JSON.stringify(result))
$scope.datatime = result.data;
console.log("czas2" + JSON.stringify($scope.datatime))
})
}
// $timeout(dataTime, 10000);
setTimeout(dataTime, 10000);
}]
})
Angularjs has a built-in $interval, you should use it instead of regular setInterval:
controller: ['$interval', '$scope', function($interval, $scope) {
function dataTime() {
console.log('function works');
}
// start interval
var interval = $interval(dataTime, 10000);
// call this method to stop interval
$scope.stop = function() {
$interval.cancel(interval);
};
}
More info about $interval
You can use setInterval instead of setTimeout, like so:
setInterval(dataTime, 10000);
In order to be able to clear the interval at a later date, you need to assign a variable the return value of setInterval and then call clearInterval with your interval as parameter, like so:
var myInterval = setInterval(dataTime, 10000);
//clear interval at some point
clearInterval(myInterval);
But since you are using AngularJS, you might use the built-in interval method that takes care of any changes that might happen in the called function and automatically trigger a digest cycle.
var angularInterval = $interval(dataTime, 10000);
And cancel it like so:
$interval.cancel(angularInterval);
Use angularjs $interval service to handle that. It is a angular service and comes with all you need in your application
stop = $interval(function() {
dataTime();
}, 100);
You can also cancel the continous execution if you want.
if (angular.isDefined(stop)) {
$interval.cancel(stop);
stop = undefined;
}
<html>
<body>
<p>Click the button to wait 3 seconds, then alert "Hello".</p>
<p>After clicking away the alert box, an new alert box will appear in 3 seconds. This goes on forever...</p>
<button onclick="myFunction()">Try it</button>
<script>
function myFunction() {
setInterval(function(){ alert("Hello"); }, 3000);
}
</script>
</body>
</html>
it will execute for every 20 secs
setInterval(function(){
$scope.callingFunction();// we can write any function
}, 20000)
Related
I have an API on q server that looks like this:
function isLoggedIn(){
....
}
This API tell whether a user is logged in or not.
I want to call this API every 15 minutes or within any interval, to check whether the user is authenticated or not on my angular app.
My concern is how to call an API in intervals, and where to write this method.
Use setInterval in your main controller.
setInterval(function(){
// call your service method here
//isLoggedIn(); in your case
}, 3000); // This is time period in milliseconds 1000 ms = 1 second.
Or
use $interval service is injected into your controller function, you can use it to schedule repeated function calls. Here is an example that used the $interval service to schedule a function call every 5 seconds:
var myapp = angular.module("myapp", []);
myapp.controller("MyController", function($scope, $interval){
$interval(isLoggedIn, 5000);
});
function isLoggedIn() {
console.log("Interval occurred");
// call your service method here
}
Here is my code that I use.
app.run(
function ( $interval, AuthService, $state, $rootScope, $http, $location, $stateParams ) {
$interval( function( event, toState, toParams, fromState, fromParams ){
AuthService.keepAlive( $rootScope, $http ).then( function( data ){
if( data.Result == "false" ){
AuthService.logout( $http, $rootScope ).then( function( data ){
$rootScope.returnToState = $location.url();
//$rootScope.returnToStateParams = toParams.Id;
$state.transitionTo("login.signin");
//event.preventDefault();
});
}
});
}, 1000 * 60 );
});
its working. I can ping server minute. I am getting response properly.
Small problem when I will remove comment from event.preventDefault I am getting event is not defined.
if possible can you please tell me.
I have a View that is updated after 1 minute, I stop the timer after before leaving this view, and all is OK.
After returning to the current view the timer don't restart again.
This is the code of the controller of this view:
.controller('IndexCtrl', function($scope, $timeout, RestService) {
var updateN = 60*1000;
$scope.test = "View 1 - Update";
var update = function update() {
timer = $timeout(update, updateN);
/** make a http call to Rest API service and get data **/
RestService.getdata(function(data) {;
$scope.items = data.slice(0,2);
});
}();
/** Stop the timer before leave the view**/
$scope.$on('$ionicView.beforeLeave', function(){
$timeout.cancel(timer);
//alert("Before Leave");
});
/** Restart timer **/
$scope.$on('$ionicView.enter', function(){
$timeout(update, updateN);
//alert("Enter");
});
})
.controller('ViewCtrl2', function($scope) {
$scope.test = "View 2";
});
I resolve the problem,
There is not a problem with the cache, but with the function update that is not called after I re-enter on the page.
I move the update function inside the $ionicView.enter :
The corrected code is:
$scope.$on('$ionicView.beforeLeave', function(){
//updateN=12000000;
$timeout.cancel(timer);
//alert("Leave");
});
$scope.$on('$ionicView.enter', function(){
//updateN=12000000;
var update = function update() {
timer = $timeout(update, updateN);
RestService.getdata(function(data) {
//console.log(tani);
//$scope.items = data;
$scope.items = data.slice(0,2);
});
}();
});
When you go back to current view, it comes from the cache, so the controller does not work again. You can disable caching in the config section of your app by adding this line of code :
$ionicConfigProvider.views.maxCache(0);
or you can disable cache on a specific view in the routing part by addding
cache : false property.
More information here and here
In your code your controller function does not call on change of view. call $timeout function outside of var update function. Each time view loads it call its controller and call anonymous or self executing functions in their scope.
.controller('IndexCtrl', function($scope, $timeout, RestService) {
var updateN = 60 * 1000;
$scope.test = "View 1 - Update";
var update = function update() {
var timer = $timeout(update, updateN);
/** make a http call to Rest API service and get data **/
RestService.getdata(function(data) {;
$scope.items = data.slice(0, 2);
});
}();
/** Stop the timer before leave the view**/
$scope.$on('$ionicView.beforeLeave', function() {
$timeout.cancel(timer);
//alert("Before Leave");
});
/** Restart timer **/
$scope.$on('$ionicView.enter', function() {
timer()
});
})
.controller('ViewCtrl2', function($scope) {
$scope.test = "View 2";
});
Can someone explain why spinerChange() function do not work properly? http://jsfiddle.net/HB7LU/9907/
<div ng-controller="naujienosControler">
<button type="button" ng-click="spinerButtonChange()">Click Me!</button>
<div class="spinner" ng-show="spiner" >
<div class="cube1"></div>
<div class="cube2"></div>
</div>
</div>
var myApp = angular.module('myApp',[]);
myApp.controller('naujienosControler', function ($scope) {
var status = true;
$scope.spiner = status;
$scope.spinerButtonChange = function(){$scope.spiner = !$scope.spiner;};
function spinerChange(){
setTimeout(function(){ alert("Why spiner dont disapear?????????"); $scope.spiner = false;}, 3000);
console.log($scope.spiner);
};
spinerChange();
});
Inject and use $timeout since you want angular to perform a digest after you do you action.
myApp.controller('naujienosControler', function ($scope, $timeout){
$timeout(function(){ $scope.spiner = false; }, 3000});
}
Edit (Thanks lechariotdor) : It's always a good practice to use "the angularjs world" wrappers since they run the $apply method that performs a digest on your scope and "syncs" the model with the change that occured.
because javascript setTimeout is a event which is not trigger in angularjs scope, so angular doesn't know about changes outside the scope.
there is a way to achieve is use $timeout instead of setTimeout as below, here is the DOC for $timeout
$timeout(function() {
$scope.spiner = !$scope.spiner;
}, 3000)
and don't forget to inject $timeout in to the controller as,
myApp.controller('naujienosControler', function ($scope, $timeout) {....
here is the update
there is another alternative using $scope.$appy() here is a good tutorial about $apply()
function spinerChange(){
setTimeout(function(){
$scope.spiner = !$scope.spiner;
$scope.$apply();
}, 3000);
};
spinerChange();
});
OR
function spinerChange(){
setTimeout(function(){
$scope.$apply(function() {
$scope.spiner = !$scope.spiner;
});
}, 3000);
};
spinerChange();
});
Use :-
$timeout(function(){ alert("Why spiner dont disapear?????????"); $scope.spiner = false;}, 500);
I'm wondering whether there is a different approach to using $watch in order to achieve the following.
Setup:
ControllerA depends on ServiceA.
ControllerB depends on ServiceB.
Current browser view is showing both controllers.
Scenario:
ControllerA is initiating a function on ServiceA, which in turn changes the value of propery X in ServiceB which should be reflected in the UI of ControllerB.
http://jsfiddle.net/zexscvax/2/
html:
<div>
<div ng-controller="ControllerA"></div>
<div ng-controller="ControllerB">Progress: {{progress}}</div>
</div>
js:
var myApp = angular.module('myApp', []);
myApp.factory('serviceA', ['$q', '$interval', 'serviceB', function ($q, $interval, serviceB) {
var service = {};
service.start = function () {
var progress = 0;
var deferred = $q.defer();
deferred.promise.then(null,null, notifyServiceB);
function notifyServiceB() {
serviceB.update(progress);
}
$interval(function() {
if (progress == 0.99) {
deferred.resolve();
} else {
progress += 0.01;
deferred.notify(progress);
}
}, 50, 100);
};
return service;
}]);
myApp.factory('serviceB', ['$rootScope', function ($rootScope) {
var service = {};
service.update = function (progress) {
console.log('update', progress);
service.progress = progress;
//$rootScope.$apply(); // <+ ERROR: $digest already in progress
};
return service;
}]);
myApp.controller('ControllerA', ['$scope', 'serviceA',
function ($scope, serviceA) {
serviceA.start();
}]);
myApp.controller('ControllerB', ['$scope', 'serviceB',
function ($scope, serviceB) {
$scope.progress = serviceB.progress;
/* this works but I'm not sure whether this is performing
$scope.$watch(function () { return serviceB.progress; },
function (value) {
$scope.progress = serviceB.progress;
}
);
*/
}]);
Without the $watch in ControllerB for the property X in ServiceB, the UI would not get updated. I've also tried injecting $rootScope in ServiceB in order to run an apply() but that wouldn't work.
I'm not entirely sure whether there's a better way to setup this scenario or whether $watch is fine. I'm a bit worried about performance issues as the value of property X changes almost every 50 ms (it's basically a visual timer counting down).
Thanks for your input.
If you don't use $watch, you can use $rootScope to broadcast, and on controller B, you can $on this event and handle the view update.
I'm attempting to set up a watch in AngularJS and I'm clearly doing something wrong, but I can't quite figure it out. The watch is firing on the immediate page load, but when I change the watched value it's not firing. For the record, I've also set up the watch on an anonymous function to return the watched variable, but I have the exact same results.
I've rigged up a minimal example below, doing everything in the controller. If it makes a difference, my actual code is hooked up in directives, but both are failing in the same way. I feel like there's got to be something basic I'm missing, but I just don't see it.
HTML:
<div ng-app="testApp">
<div ng-controller="testCtrl">
</div>
</div>
JS:
var app = angular.module('testApp', []);
function testCtrl($scope) {
$scope.hello = 0;
var t = setTimeout( function() {
$scope.hello++;
console.log($scope.hello);
}, 5000);
$scope.$watch('hello', function() { console.log('watch!'); });
}
The timeout works, hello increments, but the watch doesn't fire.
Demo at http://jsfiddle.net/pvYSu/
It's because you update the value without Angular knowing.
You should use the $timeout service instead of setTimeout, and you won't need to worry about that problem.
function testCtrl($scope, $timeout) {
$scope.hello = 0;
var t = $timeout( function() {
$scope.hello++;
console.log($scope.hello);
}, 5000);
$scope.$watch('hello', function() { console.log('watch!'); });
}
Or you could call $scope.$apply(); to force angular to recheck the values and call watches if necessary.
var t = setTimeout( function() {
$scope.hello++;
console.log($scope.hello);
$scope.$apply();
}, 5000);
You can use without $interval and $timeout
$scope.$watch(function() {
return variableToWatch;
}, function(newVal, oldVal) {
if (newVal !== oldVal) {
//custom logic goes here......
}
}, true);
It can also happen because the div is not registered with the controller. Add a controller to your div as follows and your watch should work:
<div ng-controller="myController">