4

I have a problem that I update this.customers in my controller but it does not update in the view

The relevant functions are:

//support.js

(function(){
'use strict';

var SupportCtrl = function($state, SocketFactory){
  this.user = "Will"
  this.customers = ['will','tom']
  SocketFactory.on('queue', function(queue){
    console.log(queue)
    this.customers = queue
  })
}

angular
  .module('support',[])
  .config(['$stateProvider', function($stateProvider){
    $stateProvider
      .state('support',{
        url: '/support',
        templateUrl: 'modules/support/support.html',
        controllerAs: 'support',
        controller: 'SupportCtrl'
      })
  }])

  .controller('SupportCtrl', [
    '$state',
    'SocketFactory',
    SupportCtrl
  ])

})()

//socketService.js

(function(){
'use strict';

var SocketFactory = function($rootScope){
  var socket = io.connect();
  return {
    on: function (eventName, callback) {
      socket.on(eventName, function () {  
        var args = arguments;
        console.log($rootScope)
        $rootScope.$apply(function () {
          callback.apply(socket, args);
        });
      });
    },
    emit: function (eventName, data, callback) {
      socket.emit(eventName, data, function () {
        var args = arguments;
        $rootScope.$apply(function () {
          if (callback) {
            callback.apply(socket, args);
          }
        });
      })
    }
  };
};

angular
  .module('ecomApp')
  .service('SocketFactory', [
    SocketFactory,
  ]);

})();

//support.html

<div>
  <li ng-repeat="(roomNameKey, roomName) in support.customers">{{roomNameKey}}: {{roomName}}</li>
</div>

Diagnosis

this.customers prints to the screen 0: will 1: tom But on the Socket 'queue' event the object:

{roomName: "ikp3f"}

is successfully console.logged but the angular view is not updated

I suspect this might have to do with the digest cycle and $apply() - do I need to call $apply() in my SupportCtrl?

Thanks for the help

4
  • Are you posting entire socketService.js content? Commented Feb 15, 2015 at 9:46
  • Don't know if this is the problem, but it seems as if your support module should be dependent on your ecomApp module, but I'd think you'd be seeing a different error. Commented Feb 15, 2015 at 9:54
  • 1
    You are specifying array which should contain dependency names in service definition. Just remove the array from .service('SocketFactory', SocketFactory). With this $injector will try to guess your parameters based on their names. Commented Feb 15, 2015 at 9:57
  • @PavelHoral - that fixes the $rootScope issue - thank you! Now to get the view to update... Commented Feb 15, 2015 at 9:59

1 Answer 1

2

Since you are invoking callback with

callback.apply(socket, args);

"this" in the callback will be the socket, not the controller.

Try

var SupportCtrl = function($state, SocketFactory){
  var self = this;
  self.user = "Will"
  self.customers = ['will','tom'];

  SocketFactory.on('queue', function(queue){
    console.log(queue)
    self.customers = queue
  })
}
Sign up to request clarification or add additional context in comments.

2 Comments

Yes! It works!! Question - I like using controllerAs and 'this' in controllers rather than $scope. Would this be an indication that's not the best idea?
Nope. ControllerAs is becoming a best practice. I think there are rumors that Angular 2.0 is going to do away with scope altogether. "this" can be confusing in javascript regardless.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.