0

I have two separate controllers: AuthController and NavController. AuthController is responsible for running registration/login form, and NavController is responsible for displaying navbar where I want to show current username if one is logged in. Finally, I have service "auth" that handles all that register/login stuff

auth service have this function:

auth.currentUser = function() {
  if (auth.isLoggedIn()) {
    var token = auth.getToken();
    var payload = this.decodeUsername(token);

    return payload.username;
  }
};

and NavController looks like this:

app.controller('NavController', ['$scope', 'auth',
function($scope, auth) {
    $scope.isLoggedIn = auth.isLoggedIn;
    $scope.logOut = auth.logOut;
    $scope.currentUser = auth.currentUser();
}
]);

So i can display current username, but if user just logged in NavController "doesn't know" that anything changed. I've tried to use event, but this two controllers doesn't have parent-child relation. Should I wrap them in one parent controller and do "AuthController-emit->SuperController-broadcast->NavController" or there is better way to communicate there two controllers?

tauruss85
  • 3
  • 3
  • Possible duplicate of [Angular: Share data between controllers](http://stackoverflow.com/questions/21919962/angular-share-data-between-controllers) – isherwood Nov 02 '15 at 21:30
  • @isherwood AFAIK this will only work with service property, but I'm using getter method here – tauruss85 Nov 03 '15 at 17:06

2 Answers2

0

When there is something to be shared between controllers, a Service would the best way to achieve the result. As its singleton, there will be only one instance, and your controllers - 'Auth' - can set/update value, 'Nav' can bind to the changes.

If there is some fetching involved use promise. And if the data is going to be fetched only once then you are better off by just using promise.

        auth.currentUser = function() {
           var defer = $q.defer();
           if (auth.isLoggedIn()) {
              var token =  //some asynoperation//;
              var payload = this.decodeUsername(token);

              defer.resolve(payload.username);
           }else{
              defer.reject("Not logged in");
           }

           return defer.promise;
};

(//do remember to inject $q)

VISHAL DAGA
  • 4,132
  • 10
  • 47
  • 53
0

You have two options:

Use $rootScope.broadcast (example here) and this will send an event from the top down to every controller. This works best if multiple things will want to see this message.

Or if you only ever want the navbar to be notified you could use a callback.

In your auth service have a function that gets called on state change such as

authApi.stateChange = function() {}

In your nav bar controller you then set authApi.stateChange = $scope.authUpdated; and then your authUpdated function will be notified from the service when authApi.stateChange() is called

Chris
  • 26,744
  • 48
  • 193
  • 345