AngularJS - Shared state between controllers?

I know there are other similar questions on how to pass data between Angular controllers.

What I wonder is how to deal with this in a view..

Lets say I have a UserController for login, registration etc. And an AppController for the actual app functionallity .

The UserController would be fairly easy, its sort of standalone from the rest. But what if the app needs to know about stuff from the user controller?

Lets say the app view needs to hide/show stuff depending on if the user is logged in or not. Or it could be if the user is male or female etc.

Should the app model keep its own copy of the user model state? e.g. appModel.isLoggedIn , appModel.gender etc ?

feels a bit redundant, but at the same time more testable.

So what is the correct way to do this?


ANSWERS:


Short answer

Create a service, see Creating Services for details.

Long answer

Services are - per se - application-wide singletons, hence they are perfect for keeping state across views, controllers & co.:

app.factory('myService', [ function () {
  'use strict';
  return {
    // Your service implementation goes here ...
  };
}]);

Once you have written and registered your service, you can require it in your controllers using AngularJS' dependency injection feature:

app.controller('myController', [ 'myService', '$scope',
  function (myService, $scope) {
  'use strict';
  // Your controller implementation goes here ...
}]);

Now, inside your controller you have the myService variable which contains the single instance of the service. There you can have a property isLoggedIn that represents whether your user is logged in or not.


To further specify the answer @GoloRoden gave, this is an example of how you can share state values across all controllers taking the service as a dependency.

App.factory('formState', formState);

function formState() {        

    var state = {};

    var builder = "nope";
    var search = "nope";

    state.builder = function () {
        return builder;
    };

    state.search = function () {
        return search;
    };

    state.set = {
        'builder': function (val) {
            builder = val;
        },
        'search': function (val) {
            search = val;
        }
    };

    return {
        getStateManager: function () {
            return state;
        }
    };
}

App.controller('builderCtrl', builderCtrl);

builderCtrl.$inject = ['formState']
function builderCtrl(formState) {
    var stateManager = formState.getStateManager();

    activate();

    function activate() {
        console.log("setting val in builder");
        stateManager.set.search("yeah, builder!");

        console.log("reading search in builder: " + stateManager.search());
        console.log("reading builder in builder: " + stateManager.builder());
    }
}

App.controller('searchCtrl', searchCtrl);

searchCtrl.$inject = ['formState']
function searchCtrl(formState) {
    var stateManager = formState.getStateManager();

    activate();

    function activate() {
        console.log("setting val in search");
        stateManager.set.search("yeah, search!");

        console.log("reading search in search: " + stateManager.search());
        console.log("reading builder in search: " + stateManager.builder());
    }
}


 MORE:


 ? AngularJS : $watch within directive is not working when $rootScope value is changed
 ? Trying to update factory in one controller, and have another controller notice that it has been updated?
 ? How To Use An Angular Controller Multiple Times On The Same Page?
 ? AngularJS parent directive communicate with child directive
 ? Angular bind service property to a controller scope
 ? AngularJS watch value within service
 ? var self = this?
 ? var self = this?
 ? var self = this?
 ? In knockout.js, why "this" is being assigned to "self"?