Reputation: 4353
I have an AngularJS service where I wrote the logic of button's click functionality - Setting timeout for 3 seconds to display a pop up once the button is clicked.
$timeout
is working fine as I see the output in the console. What I'm not able to do is exposing the timeoutFlag
in the HTML template on the ng-if
condition.
Could anyone please advise what I'm missing here. Appreciate the help!
Service
angular.module('myApp').service('appService', appService);
appService.$inject = ['$rootScope', '$timeout'];
function appService($rootScope, $timeout) {
button = document.getElementById('clickmeBtn');
button.addEventListener('click', function() {
$rootScope.timeoutFlag = true;
console.log('service before timeout - ' + $rootScope.timeoutFlag);
$timeout(function() {
$rootScope.timeoutFlag = false;
console.log('service after timeout - ' + $rootScope.timeoutFlag)
}, 3000)
});
}
Controller
(function() {
angular.module('myApp', []).controller('appController', appController);
appController.$inject = ['$scope', '$rootScope', 'appService'];
function appController($scope, $rootScope, appService) {
var vm = this;
}
})();
HTML
<!doctype html>
<html ng-app="myApp">
<body ng-controller="appController as vm">
<p ng-if="$rootScope.timeoutFlag">Button Clicked</p>
<button id="clickmeBtn">Click me!</button>
<script src="node_modules/angular/angular.min.js"></script>
<script src="scripts/app.controller.js"></script>
<script src="scripts/app.service.js"></script>
</body>
</html>
Upvotes: 1
Views: 93
Reputation: 48968
Because the click
event comes from outside the AngularJS execution context,
the modification of scope needs to be brought into the AngularJS execution context with the $apply
method:
angular.module('myApp').service('appService', appService);
appService.$inject = ['$rootScope', '$timeout'];
function appService($rootScope, $timeout) {
button = document.getElementById('clickmeBtn');
button.addEventListener('click', function() {
$rootScope.$apply(function() {
$rootScope.timeoutFlag = true;
});
console.log('service before timeout - ' + $rootScope.timeoutFlag);
$timeout(function() {
$rootScope.timeoutFlag = false;
console.log('service after timeout - ' + $rootScope.timeoutFlag)
}, 3000)
});
}
Only operations which are applied in the AngularJS execution context will benefit from AngularJS data-binding, exception handling, property watching, etc...
For more information, see AngularJS Developer Guide - Integration with the browser event loop
I'm still not able to display the pop up based on the
$rootScope.timeoutFlag
value in ng-if condition.
Remove the reference to $rootscope
in the HTML:
<body ng-controller="appController as vm">
<p ng-if=" ̶$̶r̶o̶o̶t̶S̶c̶o̶p̶e̶.̶ timeoutFlag">Button Clicked</p>
<button id="clickmeBtn">Click me!</button>
The scope of the controller inherits properties from $rootScope
.
The DEMO on PLNKR
Upvotes: 2