diegoaguilar
diegoaguilar

Reputation: 8376

Am I using this Angular factory wrong from controller?

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.

Upvotes: 1

Views: 119

Answers (2)

Pankaj Parkar
Pankaj Parkar

Reputation: 136194

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.

Upvotes: 2

Moses Machua
Moses Machua

Reputation: 11542

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");
}]);

Upvotes: 0

Related Questions