13

In order to have two controllers speak to each other in Angular, it is recommended to create a common service which is made accessible to both controllers. I've attempted to illustrate this in a very simple fiddle. Depending on which button you press, the app is supposed to tailor the message below the buttons.

So why isn't this working? Am I missing something obvious or more fundamental?

HTML

<div ng-controller="ControllerOne">
  <button ng-click="setNumber(1)">One</button>
  <button ng-click="setNumber(2)">Two</button>
</div>
<div ng-controller="ControllerTwo">{{number}} was chosen!</div>

JavaScript

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

app.factory("Service", function () {
  var number = 1;
  function getNumber() {
    return number;
  }
  function setNumber(newNumber) {
    number = newNumber;
  }
  return {
    getNumber: getNumber,
    setNumber: setNumber,
  }
});

function ControllerOne($scope, Service) {
  $scope.setNumber = Service.setNumber;
}

function ControllerTwo($scope, Service) {
  $scope.number = Service.getNumber();
}

3 Answers 3

17

Try creating a watch in your controller:

$scope.$watch(function () { return Service.getNumber(); },
   function (value) {
       $scope.number = value;
   }
);

Here is a working fiddle http://jsfiddle.net/YFbC2/

Sign up to request clarification or add additional context in comments.

1 Comment

My question was actually a simplified version of my actual code, which is much more complex (too much to post on SO). In my complex setup, Peter's suggestion didn't fix my issue, although it may actually be the best solution for the specific question I posed (+1). Adding a watch was exactly what I needed though, so I'm selecting this as the correct answer (in my case). Thanks everyone!
5

Seems like problem with property that holds a primitive value. So you can make these changes:

app.factory("Service", function () {
    var number = {val: 1};
     function getNumber() {
        return number;
    }
    function setNumber(newNumber) {
        number.val = newNumber;
    }
    return {
        getNumber: getNumber,
        setNumber: setNumber,
    }
});

See fiddle

Comments

3

Just call in HTML Service.getNumber() and in controller ControllerTwo call Service like:

 $scope.Service = Service;

Example:

HTML

<div ng-controller="ControllerOne">
  <button ng-click="setNumber(1)">One</button>
  <button ng-click="setNumber(2)">Two</button>
</div>
<div ng-controller="ControllerTwo">{{Service.getNumber()}} was chosen!</div>  

JS

function ControllerOne($scope, Service) {    
    $scope.setNumber = Service.setNumber;  
}

function ControllerTwo($scope, Service) {
        $scope.Service = Service;
}

Demo Fidlle

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.