简体   繁体   中英

Am I correctly using promise?

I am new to angularJs and I am trying to implement login/logout in my application.

I have an AuthService which logs user in, and a SessionService which writes the auth token to local storage (I am using jwt)

Here the AuthService:

'use strict';

angular.module('App')
.factory('AuthService', ['ApiService', 'SessionService', '$q', '$timeout', 'jwtHelper', function (ApiService, SessionService, $q, $timeout, jwtHelper) {

    // inherit
    var service = Object.create(ApiService);

    service.login = login;
    service.logout = logout;
    service.check = check;
    service.user = user;

    return service;

    function login(credentials) {
        return service.form('user.login', credentials)
            .then(function success(response) {
                SessionService.setToken(response.token);
                return response;
            });
    }

    function logout() {

        // here we use a promise so it's easier to handle
        // logout in the controller by chaining methods

        var d = $q.defer();

        $timeout(function () {
            SessionService.setToken();
            d.resolve();
        }, 0);

        return d.promise;
    }

    function check() {
        var token = SessionService.getToken();
        return !!token && !jwtHelper.isTokenExpired(token);
    }

    function user() {
        return service.call('user', {cache: true});
    }

}]);

The problem I am facing it's in the logout method. I have no server call to do, just clear the local storage and user is logged out, but I'd like to handle this with a promise so in the controller I can do the following:

       function logout() {
        AuthService.logout().then(function success() {
            $state.go('login');
        });
    }

Is this a good way of achieving this ?

I think there is no need for a promise in your particular case, and I would design it in another way :

I would store an "authenticatedUser" inside the $rootScope, with some parameters that I might find usefull (user culture, roles, ...(or just a boolean if there is no other requirement)).

In a kind of "applicationController", I would have a $watch* looking for its value :

$rootScope.$watch('authenticatedUser', function(newVal, oldVal){
    if (newVal == oldVal)
        return;

    if (newVal == null){ //User has been disconnected
        //Remove everything from screen
        //Display login form
    }
});

So, inside your controller, I would just have :

function logout() {
    AuthService.logout();
}

That way, if ever one day you decide to be able to logout from another controller (we never know what can happen ;-) ), you will just have to call your service, and everything will be done. There will be no need to duplicate code.

Also, there is something I don't understand in your code :

// inherit
var service = Object.create(ApiService);

In angular, every service is a singleton instanciated during angular bootstrap. Are you sure you want to override this default behaviour?

  • : pay attention to $watches, they cost lots of processing time during angular digest.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM