Invictus Invictus - 6 months ago 47
AngularJS Question

Web worker with angular not updating view

I have two files 1) app.js 2) worker.js

I try to update the $scope.time but it is not showing in the view.
It is my first time with webworkers. Please help.
Its my humble request please don't down vote. Instead comment.

app.js

angular.module('App', [])

.controller('MainCtrl', ['$scope', '$window', function($scope, $window) {

$scope.time = 100;

var worker = new Worker('worker.js');

worker.onmessage = function(e) {

$scope.time = e.data.time;

};

worker.postMessage($scope.time);

}]);


worker.js

self.onmessage = function(e) {
var time = e.data;

var timer = setInterval(toDo,1000);

function toDo(){

time = time-1;
postMessage({
time:time
});

}

}

Answer

When worker.onmessage is triggered it is going to be outside the Angular digest cycle. So even though you have updated the model, Angular does not know that it needs to update the views. In order for you to notify Angular that a new digest cycle has to happen you need to call $scope.$apply()

worker.onmessage = function(e) {
   $scope.$apply(function(){ 
      //do model changes here
      $scope.time = e.data.time;
   });        
};

Instead of passing an anonymous function to $scope.$apply you could just do the changes and then call $scope.$apply() with no arguments. But I believe it is preferred that you use the anonymous function with $apply as it does under the hood work like wrapping it in try...catch.

$scope.time = e.data.time;
$scope.$apply();