Search code examples
angularjsangularjs-rootscope

How to set information into index.html outside the ng-view


I'm working with angular for the first time and having some trouble showing some dynamic information in my index.html file. Everything inside the ng-view tag is working great.

When a user authenticates, a global variable with user information is put into the $rootScope and into a cookie. I've tried to access to $rootScope in the index by doing something like {{$rootScope.globals.currentUser.username}} but it doesn't work. So considering the code below, how can I show the logged user information in my index.html?

I have tried creating a controller in my app.js and putting the ng-controller on the body. While this works, it doesn't refresh when the user logout (required a page refresh to update the app controller). The same happens after the user login (it requires a whole page refresh for the information to appear).

Code to set cookie and the object in $rootScope.

function SetCredentials(username, password, token) {
  $rootScope.globals = {
    currentUser: {
      username: username,
      token: token
    }
  };

  $http.defaults.headers.common['Authorization'] = 'Bearer ' + token;
  $cookies.put('globals', JSON.stringify($rootScope.globals));
}

I also have the following index.html file. As you can see, i have set the {{$rootScope.globals.currentUser.username}} but nothing shows after the user is logged in

<!DOCTYPE html>
<html ng-app="myApp">
<head>
    <base href="/" />
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>My App</title>
    <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
    <!-- css references -->

</head>

<body class="hold-transition skin-blue sidebar-mini">
    <div class="wrapper">
        <!-- Main Header -->
        <header class="main-header">
            <!-- Header Navbar -->
            <nav class="navbar navbar-static-top" role="navigation">
                <!-- Sidebar toggle button-->
                <a href="#" class="sidebar-toggle" data-toggle="offcanvas" role="button">
                    <span class="sr-only">Toggle navigation</span>
                </a>
                <!-- Navbar Right Menu -->
                <div class="navbar-custom-menu">
                    {{$rootScope.globals.currentUser.username}}
                </div>
            </nav>
        </header>
        <!-- Content Wrapper. Contains page content -->
        <div class="content-wrapper">
            <ng-view></ng-view>
        </div>
        <!-- /.content-wrapper -->
        <!-- Main Footer -->
        <footer class="main-footer">
            <!-- To the right -->
            <div class="pull-right hidden-xs">
                something here
            </div>
            <!-- Default to the left -->
            <strong>Copyright &copy; 2016 <a href="#">NPF</a>.</strong> All rights reserved.
        </footer>
    </div>
    <!-- ./wrapper -->
    <!-- REQUIRED JS SCRIPTS -->
    <!-- jQuery 2.2.0 -->
    <script src="Scripts/jquery-2.2.3.js"></script>
    <script src="Scripts/bootstrap.js"></script>
    <script src="Scripts/app.min.js"></script>

    <script src="Scripts/linq.min.js"></script>
    <script src="scripts/angular/angular.min.js"></script>
    <script src="scripts/angular/angular-route.min.js"></script>
    <script src="scripts/angular/angular-resource.min.js"></script>
    <script src="scripts/angular/angular-cookies.min.js"></script>

    <!-- application scripts -->
    <!-- Main app -->
    <script src="app/app.js"></script>

    <!-- controllers -->
    <script src="app/home/home.controller.js"></script>

    <!-- services -->
    <script src="app/services/authentication.service.js"></script>
    <script src="app/services/user.service.js"></script>
</body>
</html>

My app file, is as follows

(function () {
'use strict';

angular
    .module('myApp', ['ngRoute', 'ngCookies', 'treeControl'])
    .constant("appSettings",
    {
        serverPath: "http://localhost:64789/",
        webApiPath: "http://localhost:64789/api/"
    })
    .config(config)
    .run(run);

config.$inject = ['$routeProvider', '$locationProvider'];
function config($routeProvider, $locationProvider) {

    $locationProvider.html5Mode({
        enabled: true,
    });

    $routeProvider
        .when('/', {
            controller: 'HomeController',
            templateUrl: 'app/home/home.html',
            controllerAs: 'viewModel'
        })

        .when('/login', {
            controller: 'LoginController',
            templateUrl: 'app/login/login.html',
            controllerAs: 'viewModel'
        })

        .when('/register', {
            controller: 'RegisterController',
            templateUrl: 'app/register/register.html',
            controllerAs: 'viewModel'
        })

        .otherwise({ redirectTo: '/login' });
};


run.$inject = ['$rootScope', '$location', '$cookies', '$http'];
function run($rootScope, $location, $cookies, $http) {
    // keep user logged in after page refresh
    try {
        $rootScope.globals = JSON.parse($cookies.get('globals'));
    }
    catch (err) {
        $rootScope.globals = {};
    }

    if ($rootScope.globals && $rootScope.globals.currentUser) {
        $http.defaults.headers.common['Authorization'] = 'Bearer ' + $rootScope.globals.currentUser.token;
    }

    //config.headers.Authorization = 'Bearer ' + authData.token;

    $rootScope.$on('$locationChangeStart', function (event, next, current) {
        // redirect to login page if not logged in and trying to access a restricted page
        var restrictedPage = $.inArray($location.path(), ['/login', '/register', '/gds']) === -1;
        try {
            var loggedIn = $rootScope.globals.currentUser;
        }
        catch (err) {

        }
        if (restrictedPage && !loggedIn) {
            $location.path('/login');
        }
    });
}})();

Solution

  • As mentioned in my comment $rootScope is not required in HTML markup expressions.

    But if you forgot to add a controller to your HTML outside of ng-view that can also cause that the variable is undefined. (No controller = no $scope)