Search code examples
angularjsangularjs-scopeangularjs-watch

AngularJS - Update another value inside watch


I am trying to update a value in my nav.html

<nav class="navbar navbar-inverse" role="navigation" ng-controller="LoginController as login">
  <div class="container-fluid">
    <ul class="nav navbar-nav">
      <li><a href="#/foo">Show option '{{login.showOption.show}}' <span class="glyphicon glyphicon-info-sign"></span></a></li>
      <li ng-if="login.showOption.show" dropdown>
          <a href class="dropdown-toggle" dropdown-toggle>
            Options <span class="caret"></span>
          </a>
          <ul class="dropdown-menu">
            <li><a ng-href>1</a></li>
            <li><a ng-href>2</a></li>
          </ul>
      </li>

    </ul>
  </div>
</nav>

The {{login.showOption.show}} is referring to this controller

'use strict';
(function (module) {

  var LoginController = function (basicauth, currentUser, growl, loginRedirect, Option, $modal, $log) {
    var model = this;
    model.showOption = Option.value;
  };

  module.controller("LoginController", ['basicauth', 'currentUser', 'growl', 'loginRedirect', 'Option', '$modal', '$log', LoginController]);

}(angular.module("civApp")));

The Option service

'use strict';
(function (module) {

  var option = function () {
    var value = {
      show: false
    };

    return {
      value: value
    };

  };

  module.service("Option", option);

}(angular.module("civApp")));

When the value of hasAccess changes, I want the nav.html also to either show or not show

'use strict';
(function (module) {
var GameController = function ($log, $routeParams, GameService, PlayerService, currentUser, Util, Option, $filter, ngTableParams, $scope, growl, $modal) {
  var model = this;

  $scope.$watch(function () {
    return GameService.getGameById(model.gameId);
  }, function (newVal) {
    if (!newVal) {
      return;
    }
    var game = newVal;
    $scope.currentGame = game;

    var hasAccess = game.player && game.player.username === model.user.username && game.active;
    $scope.userHasAccess = hasAccess;

    Option.value = {
      show: hasAccess
    };
    //$scope.apply() <-- fails
    return game;
  });


};

  module.controller("GameController",
    ["$log", "$routeParams", "GameService", "PlayerService", "currentUser", "Util", 'Option', "$filter", "ngTableParams", "$scope", "growl", "$modal", GameController]);

}(angular.module("civApp")));

But the problem is that nothing happens. I think its because I am inside a watch, and I need to either use apply or digest, but I don't know how!

Here is link to the code

The code is here: https://github.com/cash1981/civilization-boardgame/blob/feature/options/civilization-web/app/scripts/controllers/GameController.js

https://github.com/cash1981/civilization-boardgame/blob/feature/options/civilization-web/app/scripts/controllers/LoginController.js

and

https://github.com/cash1981/civilization-boardgame/blob/feature/options/civilization-web/app/views/nav.html


Solution

  • I think your service is returning false every time, you need to change your service like below.

    And one more thing you are mixing up service writing pattern with factory pattern (Reference link), here the code will look like below.

    Service

    'use strict';
    (function(module) {
    
        var option = function() {
            this.value = {
                show: false
            };
    
            this.getValue = function() {
                return this.value;
            };
    
            this.setShowValue = function(val) {
                this.value.show = val;
            };
        };
    
        module.service("Option", option);
    
    }(angular.module("civApp")));
    

    Controller

    Option.value = {
      show: hasAccess
    };
    

    will replace by

    Option.setShowValue(hasAccess);
    

    And while get the value object you could either use Option.getValue(); or Option.value

    & for show value you could do Option.value.show

    Help this could help you, Thanks :-)