3

I have an angularJS app which includes login functionality handled in the backend with express + passport; this was up until recently working fine but I've changed some things and now it is not working and I don't know how to fix my problem..

After logging in on the login page you are meant to be redirected to the index and the $scope.cUser.userName variable should have your current username however the page doesn't update the scope for userName until I actually refresh(f5) the whole page! Interestingly, the $scope.cUser.created value does update and render correctly on the page.. I can confirm that express is correctly delivering the username to angular in JSON

login method in login controller:

$scope.login = function(){
        $http.post('/users/login', {
            username: $scope.user.username,
            password: $scope.user.password
        })
        .success(function(user){
            toaster.pop('success', "Success!", "You have been logged in");  
            $rootScope.$broadcast('loggedIn', user);
            $location.path('/');
        })
        .error(function(user){
            toaster.pop('error', 'We couldn\'t log you in!', 'The provided user credentials are incorrect');
            $location.url('/login');
        });
    };

check if logged in on app run:

$http.get('/users/loggedin').success(function(user){
            if (user.loggedin !== false){
                $rootScope.$broadcast('loggedIn', user);
            } else {
                $rootScope.$broadcast('loggedOut');
            }
        });

and this is my 'mainController' which operates on the whole website outside of the ng-view:

$scope.cUser = {};
        $scope.$on('loggedIn', function(event, user){
            $timeout(function(){
                $scope.$apply(function(){
                    $scope.cUser.loggedIn = true;
                    $scope.cUser.userName = user.username;
                    $scope.cUser.created = user.created;
                });
            });
        });

        $scope.$on('loggedOut', function(event){
            $scope.cUser.loggedIn = false;
            $scope.cUser = {};
            $scope.$apply();
        });

Logging out functionality works as expected, but the $scope.cUser.userName is not being rendered on the page! Please help!

4
  • 1
    don't directly use $scope.$apply(); it could break execution if $apply is already in progress..try if(!$scope.$$phase) $scope.$apply(); Commented Jan 26, 2015 at 18:49
  • Any chance you could create a plunker or jsfiddle replicating the problem? Commented Jan 26, 2015 at 18:58
  • 1
    @pankajparkar that's just as pointless since it's in a $timeout anyway, which itself was just as pointless since the event is fired from inside Angular in a success handler. So all in all both the apply and the timeout are pointless and are a quite common anti-pattern in Angular. Commented Jan 26, 2015 at 19:19
  • @BenjaminGruenbaum Thanks for pointing. That's my bad..I missed to read full code. Commented Jan 26, 2015 at 19:21

1 Answer 1

1

try debugging by printing out both user and username in these functions

    $scope.$on('loggedIn', function(event, user){
        //$timeout(function(){ // you don't need apply or timeout here, its automatic
            //$scope.$apply(function(){ 
                console.log('logged in', user);
                $scope.cUser.loggedIn = true;
                $scope.cUser.userName = user.username;
                $scope.cUser.created = user.created;
            //});
        //});
    });

    $scope.$on('loggedOut', function(event){

        $scope.cUser.loggedIn = false;
        $scope.cUser = {};
        console.log('logged out', $scope.cUser);
        //$scope.$apply();
    });

and include cUser in you html like so:

    <div> {{cUser}} </div> <!-- this should print a json object -->

to see what is currently stored in the value.

Next, make sure you have an error scenario covered as well with your $http call:

$http.get('/users/loggedin').then(function(){
        var user = response.data;
        console.log('user', user);
        if (user.loggedin !== false){
            $rootScope.$broadcast('loggedIn', user);
        } else {
            $rootScope.$broadcast('loggedOut');
        }
    }, function(reason){
         // this is the error scenario
         console.log('error', reason);
    });

This should get you closer to answering what the issue is.

Sign up to request clarification or add additional context in comments.

4 Comments

Adding the {{cUser}} to a page showed me that after logging in before refreshing the page the JSON object only contains the loggedIn:true and created data and there is no mention of username in the JSON.. but when you refresh the page suddenly username is included in the JSON? I would have thought this is a serverside issue but its working correctly on the second http.get.. maybe there is a difference between $broadcast loggedIn after logging in and after refreshing the page (app.run)
I've fixed it! There was a mistake in the express backend - thanks so much for your help though I would never have spotted that if I hadn't have just looked at the {{cUser}}, Thanks
@imattacus, you're welcome, glad I could help you out. If it's not too much trouble could you also up-vote the answer?
I'm new to stack overflow; but I will most definitely come and upvote you when I have 15 reputation! ;)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.