1

I have a variable that I want to change when another scope changes its value.

$scope.switch = true;

var thing;
if ($scope.switch == false) {
    thing = "givesFalse";
}
else {
    thing = "givesTrue";
};
this.thingscope = thing;

So when I change $scope.switch value to false, this.thingscope should output givesFalse. In order to change the scope value, I use ng-click:

<div ng-controller="myCtrl as myCtrl" ng-app="myApp">
    {{myCtrl.thingscope}}
    <br>
    <a ng-click="switch = !switch">{{switch}}</a>   
</div>

But even that I can see that the scope does update, the variable thing doesn't seem to update at the same time. You can see the working plunkr here. Thanks in advance!

Joe82
  • 1,357
  • 2
  • 24
  • 40

2 Answers2

4

You have 2 options:

0 - Automatic: Using Watch

$scope.$watch('switch', function () {
  $scope.thing = $scope.switch ? "givesTrue" : "givesFalse";
});

1 - Manual: Use a custom function which change both values.

ng-click="switch = !switch"

change it to:

ng-click="customFunction()"

And define in the controller:

$scope.customFunction = function () {
  $scope.switch = !$scope.switch;
  $scope.thing = $scope.switch ? "givesTrue" : "givesFalse";
}
joseglego
  • 2,011
  • 1
  • 17
  • 28
  • I used the second one and it works perfect (http://plnkr.co/edit/FGovwUjEZtaRgkO85S0q?p=preview) Thanks for the approach! – Joe82 Jun 05 '16 at 14:01
  • Here is a [http://plnkr.co/edit/1DvOpeRsyXEhmQzgE7Nl?p=preview](http://plnkr.co/edit/1DvOpeRsyXEhmQzgE7Nl?p=preview) based on your previous plnkr. With both implementations: – joseglego Jun 05 '16 at 14:12
  • 1
    @joe82 - My recommendation is that you use the $scope.watch method, as that's what it's built for. Let Angular do the majority of the work for you. – Maurice Reeves Jun 05 '16 at 14:14
  • @JoséLezama in the first implementation, how is it suppose to work? I cannot switch it in the plunkr by clicking the switch link – Joe82 Jun 05 '16 at 14:18
  • My bad, I shared with an error. Please check this plnkr: http://plnkr.co/edit/g8iwAHDfzgyNgOM1DNiJ?p=preview – joseglego Jun 05 '16 at 14:23
  • I mark this as correct as the scope.watch method seem to be more recommended to do it the "angular way". Thanks again! – Joe82 Jun 05 '16 at 14:29
  • @JoséLezama in my real code, instead of text I have two functions as output. See plunker here (http://plnkr.co/edit/F4KTtQ5oOEn9a2LCjICs?p=preview) What would then be the correct way to do it? – Joe82 Jun 05 '16 at 17:26
  • 1
    @Joe82 Check the Plunkr: http://plnkr.co/edit/v8VscDRUhVd0IG0bNYjq?p=preview Please use $scope instead this (is more Angular Way). I assume you are using lodash (or underscore, I prefer lodash so I include lodash over underscore). Plus, I didn't find the ng-lodash CDN but you must use for a more elegant code. https://github.com/rockabox/ng-lodash I use it without problem. I just: - Change this to $scope - Add the lodash lib. – joseglego Jun 05 '16 at 17:38
  • @JoséLezama Thanks again, I didn't know about the ng-lodash existence, I will definitely look into it! – Joe82 Jun 05 '16 at 17:47
  • I made a related question to this one as I found a problem when applying it to my code. I leave the link in case is on your interest (http://stackoverflow.com/questions/37646216/angularjs-scope-watch-with-filtered-scopes-as-output) – Joe82 Jun 05 '16 at 20:16
1

The main point is that your Controller's code will be executed only once when your Controller is instanciated. If you want it to respond to changes, you'll need to use $watch.

$scope.$watch('switch', function(newSwitchValue, oldSwitchValue) {
  if ($scope.switch == false) {
    $scope.thing = "givesFalse";
  }
  else {
    $scope.thing = "givesTrue";
  }
});

In a real-world app where the architecture and performance matters, I would advise you to call directly a function from the ng-click.

ng-click="onClickSwitch()"

Then define the function onClickSwitch() in the $scope.

$scope.onClickSwitch = function() {
    $scope.switch = !$scope.switch;
    [code as above]
}
Neozaru
  • 1,109
  • 1
  • 10
  • 25
  • I'm not really sure how to implement it with my code, as it is slightly different, see updated plunkr (http://plnkr.co/edit/il5R7L8kOQwkCfPyetA9?p=preview) – Joe82 Jun 05 '16 at 13:50
  • http://plnkr.co/edit/i260kK85zTniDDk3nmVQ?p=preview Here is a fork without using `$watch` – Neozaru Jun 05 '16 at 14:01
  • I mark it as correct as the answer is more complete and related with my approach. Thanks! – Joe82 Jun 05 '16 at 14:08