The view is not updated in AngularJS

33,059

You are missing $scope.$apply().

Whenever you touch anything from outside of the Angular world, you need to call $apply, to notify Angular. That might be from:

  • xhr callback (handled by $http service)
  • setTimeout callback (handled by $defer service)
  • DOM Event callback (handled by directives)

In your case, do something like this:

// inject $rootScope and do $apply on it
angular.service('Channel', function($rootScope) {
  // ...
  return {
    init: function(channelId, clientId) {
      // ...
      socket.onmessage = function(msg) {
        $rootScope.$apply(function() {
          that.publish(args[0], args[1]);
        });
      };
    }
  };
});
Share:
33,059
petrov.alex
Author by

petrov.alex

Updated on December 20, 2020

Comments

  • petrov.alex
    petrov.alex over 3 years

    Updating the model property has no effect on the view when updating the model in event callback, any ideas to fix this?

    This is my service:

    angular.service('Channel', function() {        
        var channel = null; 
    
        return {        
            init: function(channelId, clientId) {
                var that = this;        
    
                channel = new goog.appengine.Channel(channelId);
                var socket = channel.open();
    
                socket.onmessage = function(msg) {
                    var args = eval(msg.data);              
                    that.publish(args[0], args[1]);
                };
            }       
        };
    });
    

    publish() function was added dynamically in the controller.

    Controller:

    App.Controllers.ParticipantsController = function($xhr, $channel) {
        var self = this;
    
        self.participants = [];     
    
        // here publish function is added to service
        mediator.installTo($channel); 
    
        // subscribe was also added with publish        
        $channel.subscribe('+p', function(name) { 
            self.add(name);     
        });                 
    
        self.add = function(name) {     
            self.participants.push({ name: name });     
        }
    };
    
    App.Controllers.ParticipantsController.$inject = ['$xhr', 'Channel'];
    

    View:

    <div ng:controller="App.Controllers.ParticipantsController">      
        <ul>
            <li ng:repeat="participant in participants"><label ng:bind="participant.name"></label></li>
        </ul>
    
        <button ng:click="add('test')">add</button>
    </div>
    

    So the problem is that clicking the button updates the view properly, but when I get the message from the Channel nothings happens, even the add() function is called