Angular service variables not updating

I have the following service (pseudo code)

app.service('user', function($http) {
    function login(email, password, callback) {
        // login user
        // set isLoggedIn to true
        // assign the returned user object to userData
        // issue callback
    };

    return {
        isLoggedIn: false,
        userData: null,
        login: login
    };
});

Here is my login controller:

app.controller('LoginController', function($scope, $http, $location, user) {
    user.login($scope.email, $scope.password, function(isSuccess, data, status) {
        if (isSuccess) { $scope.onSuccessfulLogin(); }
        else { $scope.loginStatusMessage = data; }
    });

    $scope.onSuccessfulLogin = function() {
        $location.path('/someOtherPage');
    };
});

And here is the controller used in /someOtherPage

app.controller('SomeOtherPageController', function($scope, $http, $modal, user) {
    // lots of stuff in here
    // I put a breakpoint on the first line and user.isLoggedIn is false
    // even though it was definitely set to true when the user logged in.
)};

Once the callback has been issued when login in using the user service, if the login was successful the user is taken to a different page with a different controller, where the above user service is injected. The problem is that if the login is successful, although I can see the isLoggedIn and userData variables being assigned correctly, in the new controller they remain false and null respectively.

Have I missed something here ? I need the values to be the same whenever user is injected like a singleton.

Thanks


You need to use a service, not a factory. A service is returns an instance of your function. Which means once injected everyone is going to be using the same instance. In your case you are using a factory(you have updated it since I posted my answer), and every time its injected it returns the value returned from the function. The best SO post on this is here AngularJS: Service vs provider vs factory

I tend to use services when I want to drive this point home. I want people to know if they inject this, everyone is going to be sharing the same object. I often use it with Cache's and Users.

app.service('user', function($http) {
    var that = this;

    this.isLoggedIn = false;
    this.login = function(email, password, callback) {
       that.isLoggedIn = true;
       // login user
       // set isLoggedIn to true
       // assign the returned user object to userData
       // issue callback
    };
    return this;
})

The problem here is that you are returning an object that is instantiated with null and false:

return {
        isLoggedIn: false,
        userData: null,
        login: login
    };

It should be returning another closure variable.

 return {
            isLoggedIn: myIsLoggedIn,
            userData: myUserData,
            login: login
        };

Where myUserData and myIsLoggedIn are set in the login function. Or another route is to return methods that return those values as @Sten mentioned.


Actually all services in angular are singletons. Check this stackoverflow for more info. Anywho, onto your problem, and this directly from Angular docs:

Angular services are:

Lazily instantiated – Angular only instantiates a service when an application component depends on it.

Singletons – Each component dependent on a service gets a reference to the single instance generated by the service factory.

You should be using a factory as you just need to recreate the revealing module pattern, which Angular implements through the factory, the service is a constructor function.

Both of these are besides the point that your service is simply returning null and false for both values and no matter what you change them to internally in the service the values will always be null and false. You are returning an object so you need to wire the key value pair up correctly.

app.factory('user', function($http) {
    var service = {};

    service.userData = null;
    service.isLoggedIn = false;
    service.login = function(email, password, callback) {
        // login user
        // set isLoggedIn to true
        this.isLoggedIn = true;
        // assign the returned user object to userData
        this.userData = someValue;
        // issue callback
    } 

    return service;

});
链接地址: http://www.djcxy.com/p/77830.html

上一篇: 无法在angularJs中获取我的对象的属性值

下一篇: 角度服务变量没有更新