1

I have a very simple factory:

var tv3Services = angular.module('tv3Services',[]);

tv3Services.factory('PanelService', [function(){
    var _panel = "";
    return {
        getPanel: function() {return _panel;},
        changePanel: function(newPanel) {_panel = newPanel;}
    };
}]);

And a controller which uses it:

var tv3App = angular.module('tv3App', ['tv3Services']);

tv3App.controller('AdminController', function($scope,PanelService) {


    $scope.panel = PanelService.getPanel();

    $scope.changePanel = function(panel) {
        PanelService.changePanel(panel);
    };

    $scope.changePanel("hola");

});

And this simple markup:

<html ng-app="tv3App"> 

  <head>
    <script src="service.js"></script>
    <script src="controller.js"></script>
  </head>

  <body ng-controller="AdminController">
    <h1>This should send a glyphicon when panel ONLY is same as "start"</h1>

    <div class="text-center">
      <span ng-show="panel=='start'" class="glyphicon glyphicon-star"></span>
    </div>

    <strong>Panel is set to "hola" though ...</strong>
  </body>

</html>

However, it's not working as it should at all. Panel seems not to be bound to anything. I'm calling $scope.changePanel("start"); so that should make trigger the service and assign it a value.

Why isn't this working?

I got a plunkr example.

diegoaguilar
  • 7,496
  • 12
  • 62
  • 120

2 Answers2

2

You need to call $scope.panel = PanelService.getPanel(); to set to updated value which service has or you can place $watch on service variable and update $scope.panel value on that basis.

CODE

$scope.changePanel = function(panel) {
    PanelService.changePanel(panel);
    $scope.panel = PanelService.getPanel();
};

Plunkr Here

Edit 1

The thing which you want can be doable by assigning the service getter method reference to the scope variable like scope.panel = PanelService.getPanel & while binding it on UI you could use {{panel()}} so the panel will call service getter on each digest cycle.

HTML

<strong>Panel is set to "hola" though ... But got {{panel()}}</strong>

Controller

tv3App.controller('AdminController', function($scope, $http, PanelService) {
    $scope.panel = PanelService.getPanel; //asigning getter reference
    $scope.changePanel = function(panel) {
        PanelService.changePanel(panel);
    };
    $scope.changePanel("start");
});

Updated Plunkr

Refer SO for more info

Edit 2

Another way you could maintain an array on the service, and push the new value into it, from the controller once you call getter method of service it reference get attached to the $scope variable & whenever update occurs in service changes also gets reflected in scope variable to.

Service

var tv3Services = angular.module('tv3Services', []);

tv3Services.factory('PanelService', [
  function() {
    var _panel = [];
    return {
      getPanel: function() {
        return _panel;
      },
      changePanel: function(newPanel) {
        _panel.push(newPanel);
      }
    };
  }
]);

Controller

var tv3App = angular.module('tv3App', ['tv3Services']);

tv3App.controller('AdminController', function($scope, $http, PanelService) {

    $scope.panel = PanelService.getPanel(); //scope gets binded to the service variable

    $scope.changePanel = function(panel) {
        PanelService.changePanel(panel);
    };

    $scope.changePanel("start");

});

HTML

<body ng-controller="AdminController">
    <h1>This should send a glyphicon when panel ONLY is same as "start"</h1>
    <div class="text-center">
        <span ng-show="panel=='start'" class="glyphicon glyphicon-star"></span>
    </div>
    <strong>Panel is set to "hola" though ... But got {{panel[0]}}</strong>
</body>

Edit2 Plunkr Here , One more good example in Plunkr

Thanks.

Community
  • 1
  • 1
Pankaj Parkar
  • 127,691
  • 20
  • 213
  • 279
  • I see it works that way. However I have another example with SAME pattern, storing an array and with a getter and setter functions and it "works", it's bound even by only having a `$scope.panel = service.getPanel()`. – diegoaguilar Feb 25 '15 at 22:44
  • This is the plunkr of the case I mention: http://plnkr.co/edit/YTLBPCGfoeCKDMlJDfGA?p=info What differences are between that working and the one in my post? – diegoaguilar Feb 25 '15 at 22:44
  • because your service is broadcasting an event, you can do either by using $watch as i mentioned or you mentioned plunkr way by this line `$rootScope.$broadcast("itemAdded",item.place)` event – Pankaj Parkar Feb 25 '15 at 22:48
  • I'ts not about the broadcast, even I would get rid of that, this second example works while other doesn't. – diegoaguilar Feb 25 '15 at 22:53
  • @diegoaguilar as far as you convert service variable to array it start the two way binding take a look at our example http://plnkr.co/edit/Gy4WBFwzltawxYms2dMt?p=preview – Pankaj Parkar Feb 25 '15 at 23:16
  • This may help you http://stackoverflow.com/questions/16023451/binding-variables-from-service-factory-to-controllers – Pankaj Parkar Feb 25 '15 at 23:22
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/71725/discussion-between-pankajparkar-and-diegoaguilar). – Pankaj Parkar Feb 25 '15 at 23:30
  • Sorry, I really couldn't chat last time. I really think you should edit your question in order to explain what the issue really was and how it should have been fixed. Thanks! – diegoaguilar Feb 26 '15 at 03:51
  • Feel free to edit answer..if you want..otherwise I'll unpadte the answer after couple of hour.. – Pankaj Parkar Feb 26 '15 at 04:14
  • 1
    I think you should edit it and then I will if I need it – diegoaguilar Feb 26 '15 at 04:23
  • @diegoaguilar I added the answer..i think Edit2 part description is somewhat not good, please you can improve it..Thanks.. :) – Pankaj Parkar Feb 26 '15 at 17:46
  • @diegoaguilar did you look at my answer? – Pankaj Parkar Feb 27 '15 at 17:02
0

Where you use your service, try to explicitly declare your service name in case of minification which will rename your variables. Try this;

tv3App.controller('AdminController',['$scope','PanelService',
function($scope,PanelService) {
    $scope.panel = PanelService.getPanel();
    $scope.changePanel = function(panel) {
        PanelService.changePanel(panel);
    };

    $scope.changePanel("hola");
}]);
Moses Machua
  • 9,544
  • 3
  • 29
  • 46