0
votes

This is a question of best practice.

I have an angular application with some nested states and views.

When my user hits the "Sign out" button, it's attached to a controller function, the controller function then calls a function in an authentication service. The authentication service then makes a call to the server and somewhere along there the user needs to be redirected to the login page.

I've had a few trains of thought with where the actual "state.go('login')" should be.

(1) The service makes the call to the server and when that call finishes, the service changes state to login.

This feels bad because in my mind a service should be some static entity that provides data or functionality and is separated from the rest of the app.

(2) The controller changes the state to login after calling the authentication service.

This seems better. The controller is attached the application and the markup already anyways.

(3) The service emits a custom action that I define in an app constant like EVENTS.LOGOUT_SUCCESSFUL, and then on the root scope I listen for that event and do the state.go in the event listener.

Not sure about this one, it makes things more complicated but seems fairly clean.

Any thoughts?

2

2 Answers

2
votes
    Change your State in the Controllers. Refer to following example ...

----------------------------------------------------------------------------
# config.js

(function() {
    'use strict';

    angular
        .module('app.foo.authentication')
        .config(moduleConfig);

    /* @ngInject */
    function moduleConfig($translatePartialLoaderProvider, $stateProvider) {
        $translatePartialLoaderProvider.addPart('app/foo/authentication');

        $stateProvider

        .state('authentication.logout', {
            url: '/logout',
            templateUrl: 'app/foo/authentication/logout/logout.tmpl.html',
            controller: 'LogoutController',
            controllerAs: 'vm'
        });
    }
})();

    -------------------------------------------------------------------------
    # logout.controller.js

    (function() {
        'use strict';

        angular
            .module('app.foo.authentication')
            .controller('LogoutController', LogoutController);

        /* @ngInject */
        function LogoutController(
            $scope,
            $state,
            $mdToast,
            $filter,
            $http,
            $window,
            triSettings,
            session) {
            var vm = this;
            vm.triSettings = triSettings;
            vm.backToLogin = backToLogin;
            vm.loading = false;

            function backToLogin () {
                vm.loading = true;
                session.end();
                $window.location.reload();
                $state.go('authentication.login');
            }
        }
    })();

    ----------------------------------------------------------------------------

    # logout.html

    <div layout="row" flex layout-padding layout-fill layout-align="center center">
        <div class="logout-card" flex="40" flex-lg="50" flex-md="70" flex-xs="100">
            <md-card>
                <md-toolbar class="padding-20 logout-card-header">
                    <div layout="row" layout-align="center center">
                        <img ng-src="{{::vm.logo}}" alt="{{vm.name}}">
                    </div>
                    <div layout="row" layout-align="center center">
                        <h1 class="md-headline" translate>LOGOUT.TITLE</h1>
                    </div>
                </md-toolbar>

                <md-content class="md-padding">
                    <p translate>LOGOUT.MESSAGES.SUCCESS</p>

                    <div layout="row" layout-align="center center">
                        <md-progress-circular ng-show="vm.loading" md-mode="indeterminate"></md-progress-circular>
                    </div>

                    <form name="logout">
                        <md-button
                            class="md-raised md-primary full-width margin-left-0 margin-right-0 margin-top-10 margin-bottom-10"
                            ng-click="vm.backToLogin()"
                            translate="LOGOUT"
                            aria-label="{{'LOGOUT' | translate}}">
                        </md-button>
                    </form>
                </md-content>
            </md-card>
        </div>
    </div>
1
votes

I agree with your thoughts and would prefer 2 over 3 if this is the only flow to logout.

If there are different ways to logout (e.g forced logout), option 3 makes more sense to me.