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! ;)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.