-1

I'm doing a broadcast and on listening to the broadcast i'm trying to updated a variable on the scope that I wanted to display on the view, but the changes are not being reflected in the view immediately, until I click on the UI. Anyone know what should be done at this point, I don't want to use $apply. Here, please find my code.

rApp.factory('pService', ['$http', '$rootScope', '$sanitize', 

function ($http, $rootScope, $sanitize) {

 var pService = {};

 //Some other code

 pService.Update=function(status)
 {
   if(status.LastItemId!=undefined)
   {
     pService.disItemId = status.LastItemId;
     $rootScope.$broadcast('updated',pService.disItemId);    
   }
 }

 //Some other code

return pService;

});


rApp.controller('dController', ['$scope','$rootScope' 'pService' ,dController]);

function dController($scope,$rootScope, pService) {

$rootScope.$on('updated',function (event, data) {
            $scope.lastItemId = data; // I want to display the lastItemId on UI
    })
});
Ajay Srikanth
  • 1,095
  • 4
  • 22
  • 43
  • 1
    You are missing event name. `$scope.$on('updated', function...` closing for typo – PSL Jun 05 '15 at 21:20
  • Another one.. where is `dispenseController` ? Also check for syntax error. you seem to have got that too.. – PSL Jun 05 '15 at 21:22

2 Answers2

0

What triggers the event being sent, i.e. where does your service's update() method get called? You may need to use apply to trigger a digest cycle if it is called from outside angular. I see from the comment you are using SignalR, that will not create a digest cycle to update bindings in angular. Try wrapping your call in an apply like this:

$rootScope.$apply(function(scope) {
    service.Update();
});

You also don't need to use $rootScope.on(), you can just use $scope.on(). Broadcasts on the root scope will go down to all child scopes. If the message isn't used elsewhere, you can use $rootScope.emit() which bubbles upward and won't go down through all your child scopes.

Jason Goemaat
  • 28,692
  • 15
  • 86
  • 113
  • do you mean $broadcast ? if that is the case it is in my service which is above. In fact everything is angular – Ajay Srikanth Jun 05 '15 at 21:27
  • Update() method will be called by a different method in the service, which will then update the variables. – Ajay Srikanth Jun 05 '15 at 23:34
  • 'by a different method in the service' - when is THAT method called? There has to be something that initiates that call, whether it is a user clicking a button, a timer, or the return from an ajax call. If any of these are initiated from outside angular, a digest cycle will not be triggered and your code will not be executed. – Jason Goemaat Jun 06 '15 at 22:41
  • it will be triggered by a message from signalR – Ajay Srikanth Jun 08 '15 at 22:12
  • ah, try wrapping the call to your service in an apply – Jason Goemaat Jun 09 '15 at 17:56
0

Ideally Services are used for sharing common methods in different controllers. It's good to return this. Also, if you need to return the value to controller, instead using events why don't you simply return the value from a service public method and access the value in controller. Also, it's the controllers' work to initiate or call services' method and update corresponding scopes. Firing event from a service to notify controller is similar to what firing events from one controller to other. Services are not made for that purpose. See my code for reference.

DEMO - http://plnkr.co/edit/Co7ka0sZKZgYk5Oz88Np?p=preview

JS:

var app = angular.module('myApp', []);
app.controller('myController', ['$scope', '$rootScope', 'pService', function ($scope, $rootScope, pService) {
  $scope.name = 'softvar';
  $scope.itemId = pService.Update({LastItemId: 4})

}]);

app.factory('pService', [ '$rootScope', function ( $rootScope) {

 this.pService = {};

 //Some other code

 this.Update= function(status) {
   if (status.LastItemId) {
     this.pService.disItemId = status.LastItemId;
     console.log(this.pService.disItemId)
     return this.pService.disItemId;    
   }
 }

  //Some other code
  return this;

}]);

HTML:

<body ng-app="myApp" ng-controller="myController">
    <h1>ItemId is:  {{itemId}}!</h1>
</body>

UPDATE:

DEMO - http://plnkr.co/edit/Co7ka0sZKZgYk5Oz88Np?p=preview

JS:

var app = angular.module('myApp', []);
app.controller('myController', ['$scope', '$rootScope', 'pService', function ($scope, $rootScope, pService) {
  $scope.name = 'softvar';

  $scope.$on('serviceUpdated', function (ev, data) {
    $scope.itemId = data;
  });

  pService.Update({LastItemId: 4});

}]);

app.factory('pService', [ '$rootScope', function ( $rootScope) {

 this.pService = {};

 //Some other code

 this.Update= function(status) {
   if (status.LastItemId) {
     this.pService.disItemId = status.LastItemId;
     console.log(this.pService.disItemId)
     $rootScope.$broadcast('serviceUpdated', this.pService.disItemId);   
   }
 }

  //Some other code
  return this;

}]);
softvar
  • 17,917
  • 12
  • 55
  • 76
  • Thanks for the response, but part of my problem here is that my controller doesn't know when the value in the service is changed. I need to trigger that change from service to the controller. – Ajay Srikanth Jun 05 '15 at 23:34
  • I understand. Please see my updated answer. hope it answers your question well. – softvar Jun 06 '15 at 07:57
  • myController is not the one actually triggering the update in my service. – Ajay Srikanth Jun 06 '15 at 18:46