when do you need to call $apply()
? Very rarely, actually.
The $apply()
function is useful when integrating AngularJS with outside code or non angularJs Javascript code residing in your application. Here we are using a JS function to use event listener so we might have to wrap it with apply to actually get it applied in AngularJs Basically apply/digest updates the binding.
document.getElementById("updateTimeButton") .addEventListener('click', function() { $scope.$apply(function() { console.log("update time clicked"); $scope.data.time = new Date(); }); });
Notice how the $scope.$apply()
function is called from inside the button event listener, and how the update of the$scope.data.time
variable is performed inside the function passed as parameter to the $apply()
function. When the $apply()
function call finishes AngularJS calls $digest()
internally, so all data bindings are updated.
AngularJS actually calls almost all of your code within an $apply call. Events like ng-click
, controller initialization, $http
callbacks are all wrapped in $scope.$apply()
. So you don’t need to call it yourself, in fact you can’t. Calling $apply inside $apply will throw an error.
You do need to use it if you are going to run code in a new turn. And only if that turn isn’t being created from a method in the AngularJS library. Inside that new turn, you should wrap your code in $scope.$apply()
.
AngularJS provides wrappers for common native JS async behaviors:
- Events =>
ng-click
- Timeouts =>
$timeout
- jQuery.ajax() =>
$http
This is just a traditional async function with a $scope.$apply()
called at the end, to tell AngularJS that an asynchronous event just occurred.
$scope.$apply()
should occur as close to the async event binding as possible.
Do NOT randomly sprinkle it throughout your code. If you are doingif (!$scope.$$phase) $scope.$apply()
it’s because you are not high enough in the call stack.
Whenever possible, use AngularJS services instead of native. If you’re creating an AngularJS service (such as for sockets) it should have a $scope.$apply()
anywhere it fires a callback.