Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make AngularJS refresh header after login

I created web-application, in which there is a redirect after login to welcome page, but the header is not updated in this case. Here is my Angular code:

MyApp.controller('LoginController', function ($scope) {
    $scope.login = function () {
        login();
        var name = "";
        if (document.cookie.indexOf("name") !== -1)
            name = document.cookie.split('=')[2];

        $scope.menu = [
            {
                title: 'Product',
                url: 'product'
            },
            {
                title: 'About',
                url: 'about'
            },
            {
                title: 'Contact',
                url: 'contact'
            },
            {
                title: name,
                url: 'welcomeUser'
            },
            {
                title: 'LogOut',
                url: 'logout'
            }
        ];

        $scope.refresh();
    };
});

MyApp.controller('MainController', function ($scope) {
    var name = "";
    if (document.cookie.indexOf("name") !== -1)
        name = document.cookie.split('=')[2];
    if (document.cookie.indexOf("name") === -1 && (name === "" || name === undefined)) {
        $scope.menu = [
            {
                title: 'Product',
                url: 'product'
            },
            {
                title: 'About',
                url: 'about'
            },
            {
                title: 'Contact',
                url: 'contact'
            },
            {
                title: 'Register',
                url: 'register'
            },
            {
                title: 'Login',
                url: 'login'
            }
        ];
    } else {
        $scope.menu = [
            {
                title: 'Product',
                url: 'product'
            },
            {
                title: 'About',
                url: 'about'
            },
            {
                title: 'Contact',
                url: 'contact'
            },
            {
                title: name,
                url: 'welcomeUser'
            },
            {
                title: 'LogOut',
                url: 'logout'
            }
        ];
    }
});

Angular config code:

MyApp.config(function ($routeProvider, $locationProvider) {
    $routeProvider
        .when('/home', {
            templateUrl: 'partials/home.html',
            controller: 'MainController'
        })
        .when('/login', {
            templateUrl: 'partials/login.html',
            controller: 'LoginController'
        })
        .otherwise({
            redirectTo: '/404'
        });
});

And here is my JS code for POST request sending - login user function:

function login() {
    var username = document.getElementById('usernameLogin').value;
    var password = document.getElementById('passwordLogin').value;

    if (!username.trim() || username.length === 0 || !password.trim() || password.length === 0) {
        document.getElementById('wrong_username').style.display = 'block';
        document.getElementById('wrong_password').style.display = 'block';
        return;
    }

    var json = {
        username: username,
        password: sha1(password)
    };

    $.ajax({
        type: "POST",
        url: "http://localhosts:7777/account_management/login_user",
        data: JSON.stringify(json),
        contentType: "application/json; charset=utf-8",
        success: function (data) {
            if (data === "true") {
                document.cookie = "";
                document.cookie = "username=" + username;
                window.location.href = "/#/welcomeUser";
            } else if (data === "false") {
                document.getElementById("wrong_password").style.display = "block";
            } else {
                alert(data);
            };
        },
        failure: function (errMsg) {
            alert(errMsg);
        }
    });
}

The authorization itself works fine, but $scope.menu updates only after page refresh.

Is there any ideas how to fix it?

like image 961
Taras Kovalenko Avatar asked Apr 17 '15 07:04

Taras Kovalenko


3 Answers

MainController ad LoginController are two different controllers and are having different scopes.

Changing $scope.menu in one doesn't change in another as they don't have any parent child relationship.

You must either have the menu in $rootScope and then update it in the respective controllers after login.

MyApp.controller('LoginController', function ($scope, $rootScope) {
  $rootScope.menu = [];
});

MyApp.controller('MainController', function ($scope, $rootScope) {
  $rootScope.menu = []; // update the menu
});

Else, have it as a service so that you can use $emit event and in it to update the menu once the user has logged in.

The function login() {...} must be part of a service. You must avoid using jQuery in an angular project. Use $http inside service which is preferable and provides same functionality as $.ajax

like image 136
mohamedrias Avatar answered Oct 23 '22 21:10

mohamedrias


Instead of having your menu in $rootScope, you could use event to warn your menu that the user has logged in and that he should reload itself.

On LoginController

$rootScope.$broadcast('userLoggedIn');

On MainController

$rootScope.$on('userLoggedIn', function () {
    //Code to apply modification to your menu
});

If you have to pass parameters, you can use the second argument of $broadcast method like this :

$rootScope.$broadcast('userLoggedIn', {key: 'value'});

$rootScope.$on('userLoggedIn', function (params) {
    console.log(params.key); //value
});
like image 36
Blackus Avatar answered Oct 23 '22 21:10

Blackus


Solution 1 :

You need to use $rooteScope for call scope variables from another controller.

Please use $rooteScope.objectName in your login controller instead of using$scope.objectName.

Like

// Assign the menu details on scope variable in main controller

MyApp.controller('MainController', function ($scope) {
  $scope.menu = [
            {
                title: 'Product',
                url: 'product'
            },
            {
                title: 'About',
                url: 'about'
            },
            {
                title: 'Contact',
                url: 'contact'
            },
            {
                title: 'Register',
                url: 'register'
            },
            {
                title: 'Login',
                url: 'login'
            }
        ];
});

//then call the scope variables via rootScope from login controller

MyApp.controller('LoginController', function ($scope,$rootScope ) {
  $rootScope.menu = [
            {
                title: 'Product',
                url: 'product'
            },
            {
                title: 'About',
                url: 'about'
            },
            {
                title: 'Contact',
                url: 'contact'
            },
            {
                title: 'Register',
                url: 'register'
            },
            {
                title: 'Login',
                url: 'login'
            }
        ];
});

Solution 2

Your window.location.href = "/#/welcomeUser"; is a javascript code, So it is not consider the scope objects

You need to change window.location.href = "/#/welcomeUser"; to $location.path('/#/welcomeUser');

also you need to configure the $location on your controller

Solution 3

If above two solutions are not working, you need to manually reload the page by using $route.reload()

But the third solution is not good, because it will make a page reload. But it's solve your issue to manually reload the screen.

like image 3
Ramesh Rajendran Avatar answered Oct 23 '22 20:10

Ramesh Rajendran