0

I am new using AngularJS, i am interesting about the fact that when we update a data, Angular automatically impacts the modifications everywhere the data is involving. But unfortunately, i can't make it works.

The simple thing i am trying to do is to make a change on a controller B, and i want the changes to be achieve on the controller A, since the data is referering to the same Service. The data is correctly impacting on the both controllers, but the DOM is not updating according to this modification, here is the test:

HTML

<body>
  <div ng-controller="ACrtl">
    <h1>{{is_logged}}</h1>  <!-- Always false -->
    <button ng-click="check()">Check</button> <!-- true/false -->
  </div>
  <div ng-controller="BCrtl">
    <button ng-click="{{is_logged=!is_logged}}">Toggle throught the DOM</button> <!-- Doesn't change anything on the Javascript -->
    <button ng-click="toggle()">Toggle throught the controller</button> <!-- Change the Javascript but doesn't impact the other controller's scope -->
  </div>
</body>

JS

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

app.controller('ACrtl', function($scope, UserService) {
  $scope.is_logged = UserService.is_logged;  

  $scope.check = function() {
    console.log('is_logged='+UserService.is_logged); //The change is correctly made when changin is_logged on the controller B.
    $scope.is_logged = UserService.is_logged;
  };
});

app.controller('BCrtl', function($scope, UserService) {
  $scope.is_logged = UserService.is_logged;

  $scope.toggle = function() {
      UserService.is_logged = !UserService.is_logged;
  };
});

app.factory('UserService', function() {
  var User = {
    is_logged: false
  };

  return User;
});

I hope AngularJS is able to do this and it's something i am doing wrong in my code !

Here is a plunker

Ludo
  • 5,060
  • 15
  • 53
  • 85

2 Answers2

1

When you assign is_logged to the scope on each controller you are creating a new property on each controller, both of which are initialised to the value from UserService.

In your case what you can do is expose the service on the scope of each controller like so:

$scope.data = UserService

and in your view:

<h1>{{data.is_logged}}</h1>

Have a look at this answer and the links that it mentions.

Community
  • 1
  • 1
Gruff Bunny
  • 27,738
  • 10
  • 72
  • 59
1

Primitive variables (like boolean) are passed by value in Javascript, and the variables $scope.is_logged are just copies of their values in the service. So, if the original service value is changed, then this won't affect any copies on the scopes.

A standard way or re-factoring this would be to share an object between the controllers, and not a primitive, so

app.factory('UserService', function() {
  return {
    status: {
      is_logged: false
    }
  };
});

And then used in the controllers

$scope.status = UserService.status;

So the controller can change $scope.status.is_logged, and the changes will be seen in all the controllers.

You can see this at:

http://plnkr.co/edit/GLZmdsAnn3T5Xw80h4sV?p=preview

Michal Charemza
  • 25,940
  • 14
  • 98
  • 165