AngularJS and WebSockets: Callback function needs $scope.$apply() to work

I am using AngularJS and a phone web service to make calls through WebSockets.
The web service has several callbacks such as Phone.onIncomingCall

When I use this function to set a $scope variable the view is not updated automatically except if I use $scope.$apply right after.

Phone.onIncomingCall = function(){
  $scope.myVar = "newValue";
  $scope.$apply(); // only works if I call this line
};

What is the reason for this behaviour (is it expected) and is there a way around using $scope.apply() in each function?

Answers:

Answer

Angular is "unaware" of the update to the scope variable you've made, since you're updating it from outside of the Angular context. From the docs for $apply:

$apply() is used to execute an expression in angular from outside of the angular framework. (For example from browser DOM events, setTimeout, XHR or third party libraries). Because we are calling into the angular framework we need to perform proper scope life cycle of exception handling, executing watches.

By running $apply on the scope, $digest is called from $rootScope, which will trigger any $watchers registered on $scope.myVar. In this case, if you're using the variable in your view via interpolation, this is where the $watcher was registered from.

Answer

It is the expected behavior, angular works like that internally.

I recommend the following:

Phone.onIncomingCall = function () {
    $scope.$apply(function () {
      $scope.myVar = 'newValue';
    });
}

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us Javascript

©2020 All rights reserved.