5

Currently have a small application with a

  • login view '/login'
  • homepage view '/home'
  • logged-in-homepage view '/dashboard'

when the user navigates to the homepage after being loggedin i wanted to show him the logged-in-homepage. I tried giving a redirectUrl to the $routeProvider. If i return an empty string there it stays on the page, and if it returns a string like '/dashboard' then it redirects to the dashboard.

the problem is i cannot check whether the user is logged in, in that function in the config. because I cannot inject my UserService in there.

main.js

var myApp = angular.module('myApp', ['ngRoute', 'ngAnimate']);

myApp.config(['$routeProvider', '$locationProvider', function AppConfig($routeProvider, $locationProvider) {

    $routeProvider.when(
        // entry point, the main route of the app
        '/', {
            redirectTo: '/home'
        }
    )
    .when(
        // home page, entrypoint when a user is not logged in.
        '/home', {
            redirectTo: function redirectHome() {
                // need to get the loggedInState here... preferably not on the window :p
                return (window.isLoggedIn) ? "/dashboard" : "";
        },
            action: 'splash.home'
        }
    )
    .when(
        // specific route to the login popup on the homepage
        '/login', {
            action: 'splash.home.login'
        }
    )
    .when(
        // dashboard after being logged in
        '/dashboard', {
            action: 'base.dashboard'
        }
    )
});

the UserService which holds user state:

myApp.service('UserService',
    [
        '$http',
        function UserService($http) {

            // --- Service Variables. ------------------- //

            // url to the service that returns the logged in user details
            var userServiceUrl = '/user/data/me';

            // Store the current user.
            var User = {
                isLogged: false,
                apps: [],
                data: {}
            };

            // --- Service Methods. ------------------- //

            // Return whether the user is logged in
            function isLoggedIn() {
                return User.isLogged;
            }

            // Return the current user
            function getUser(fn) {
                fn = fn || function callback() {};

                if (!User.isLogged) {
                    return fetchUser(fn);
                } else {
                    return fn(User);
                }
            }

            // set the current user
            function setUser(user, loggedIn) {
                loggedIn = loggedIn || false;
                User.isLogged = loggedIn;
                User.data = user;
            }

            // get the user from the server
            function fetchUser(fn) {
                $http.get(userServiceUrl).success(function onGetUserSuccess(data, status, headers, config) {
                    if (data.success) {
                        setUser(data.data, data.success);
                    }

                    if (fn !== undefined) {
                        fn(User);
                    }
                })
                .error(function onGetUserError(data, status, headers, config) {
                    setUser({}, false);
                });
            }

            // --- Return Public API. ------------------- //

            return {
                isLoggedIn: isLoggedIn,
                getUser: getUser,
                setUser: setUser
            };

        }
    ]
);

is there a way to get to the user state from the config? without it being public (I don't want to make the user accessible on the window object for example...)

or should i get that info from a cookie, or other system?

Sander
  • 13,301
  • 15
  • 72
  • 97
  • Why can't you inject your UserService into your AppConfig function? – Joe White Sep 16 '13 at 11:42
  • because, i get the error `Uncaught Error: [$injector:modulerr] Failed to instantiate module myApp due to: Error: [$injector:unpr] Unknown provider: UserService`, as described in this post: you can only include factories in a module config function (http://stackoverflow.com/a/17486617/109341) – Sander Sep 16 '13 at 11:58

1 Answers1

0

Change service by factory and inject it in your run block not in your config as dependency.

In fact if you want to use a service provider and not a facotry you have to attach your functions to this. If you use the return statement use a factory.

It should be works.

Another method is to use an httpInterceptor to know if the user is logged or not ... That's a common pattern. If you want to know ask and i'll explain you in details.

Thomas Pons
  • 7,709
  • 3
  • 37
  • 55
  • I have seen references to the httpinterceptor and will take a look at the concept tonight. I don't get your remark on using it in the `run` block though, as I need it in the `Config` where the routes are being specified. – Sander Sep 16 '13 at 12:57
  • No matter. Delete your question if you think that is solved. httpInterceptor is the right way for authentication and authorization. Good Luck & Happy coding ! – Thomas Pons Sep 16 '13 at 12:58
  • Oh i think use a cookie for authentication with a token, and an httpInterceptor to get the response from the server and check the status code: 401 not logged & 403 unauthorize. – Thomas Pons Sep 16 '13 at 13:03