How to properly display header/footer using angularjs and ui-router?

Issue

This is my index.html:

<body>
    <div ui-view></div>
</body>

This is my app.js:

angular.module('sample', [
            'auth0',
            'ngRoute',
            'sample.home',
            'sample.header',
            'sample.login',
            'ui.router',
            'angular-storage',
            'angular-jwt'
        ])
        .config(function myAppConfig($stateProvider, $urlRouterProvider, $routeProvider, authProvider, $httpProvider, $locationProvider,
            jwtInterceptorProvider) {

            $stateProvider
                .state('login', {
                    url: '/login',
                    templateUrl: 'login/login.html',
                    controller: 'LoginCtrl'
                }).state('root', {
                    url: '/',
                    abstract: true,
                    views: {
                        'header': {
                            templateUrl: 'home/header.html',
                            controller: 'HeaderCtrl'
                        },
                        'footer': {
                            templateUrl: 'home/footer.html'
                        }
                    },
                    data: {
                        requiresLogin: true
                    }
                }).state('root.home', {
                    url: '/',
                    views: {
                        '@': {
                            templateUrl: 'home/home.html'
                        }
                    },
                    data: {
                        requiresLogin: true
                    }
                })
            $urlRouterProvider.otherwise('/');

            authProvider.init({
                domain: AUTH0_DOMAIN,
                clientID: AUTH0_CLIENT_ID,
                loginUrl: '/login'
            });

            jwtInterceptorProvider.tokenGetter = function(store) {
                return store.get('token');
            }

            $httpProvider.interceptors.push('jwtInterceptor');
        })
        .run(function($rootScope, auth, store, jwtHelper, $location, $state, $stateParams) {
            $rootScope.$on('$locationChangeStart', function() {
                if (!auth.isAuthenticated) {
                    var token = store.get('token');
                    if (token) {
                        if (!jwtHelper.isTokenExpired(token)) {
                            auth.authenticate(store.get('profile'), token);
                        } else {
                            $location.path('/login');
                        }
                    }
                }
            });
        })
        .controller('AppCtrl', function AppCtrl($scope, $location) {
            $scope.$on('$routeChangeSuccess', function(e, nextRoute) {
                if (nextRoute.$$route && angular.isDefined(nextRoute.$$route.pageTitle)) {
                    $scope.pageTitle = nextRoute.$$route.pageTitle + ' | Auth0 Sample';
                }
            });
        })

If I do login & the root that’s commented out, everything works fine. But I need to put in a header and footer (the files are correct) and when I try the root + root.home, I get a blank screen with no errors on the browser’s console either.

I’m trying to go off of a few examples from online (such as this one) but none are working out so I don’t know what I’m doing wrong.

Right now my header/footer.html just say header/footer.html while home has a button on it.


Added the full app.js in case that helps. Each html (footer/header/home) just has

<h1>Home</h1>
<div ui-view></div>

Edit: index.html

<body>
    <div ui-view="header"></div>
    <div ui-view></div>
    <div ui-view="footer"></div>
</body>

app.js

.state('root.home', {
            url: '/',
            views: {
                '@': {
                    templateUrl: 'views/home.html',
                    controller: 'HomeCtrl'
                }
            },
            data: {
                requiresLogin: true
            }
        })

Solution

I believe your issue here is your route is looking for a view named container not a class.

<div ui-view="container"></div>

Since it can’t find a view named that it does not insert anything in the view.

Or you can just change your view route to be:

views: {
            '@': {
                templateUrl: 'home/home.html'
            } 

Which will tell it to insert that HTML in the first unnamed view it finds.

You can find a break down of how nested views work with UI-Router here

Assuming your home.html looks like this:

<div ui-view="header"></div>
<div ui-view="footer"></div>

your route should be something like

 views: {
                'header@home': {
                    templateUrl: 'home/header.html',
                    controller: 'HeaderCtrl'
                },
                'footer@home': {
                    templateUrl: 'home/footer.html'
                }
            },
            data: {
                requiresLogin: true
            }

Answered By – ToddB

Answer Checked By – Mary Flores (AngularFixing Volunteer)

Leave a Reply

Your email address will not be published.