Thomas
Thomas

Reputation: 5099

Angular.js $modal Scope issues

I am trying to create a simple login modal with username and password. To accomplish this, I used a factory for handling login variables across controllers:

.factory('userFactory', function($http) {
    var userInfo = {
        isLogged: false
    };  
    return {
        getUserInfo: function () {
            return userInfo;
        },


        loginNonce: function(loginObj) {
            return $http.get('http://exmple.com/?json=get_nonce&controller=auth&method=generate_auth_cookie').success(
            function(data, status, headers, config) {
                var nonce = data.nonce;
            }); 
        },

        login: function(loginObj) {
            var nonce = loginObj.nonce; 
            return $http.get('http://example.com/?json=auth/generate_auth_cookie&nonce='+nonce+'&username='+loginObj.username+'&password='+loginObj.password).success(function(data, status, headers, config) {
                if (data.status == 'ok') {

                    var userInfo = {
                        isLogged: true,
                        username: data.user.username,
                        userAvatar: data.user.avatar,
                        firstName: data.user.firstname,
                        lastName: data.user.lastname
                    }
                    return userInfo;
                } else {
                    var userInfo = {
                        isLogged: false,
                        username: '',
                        errorMsg: data.error
                    }
                    return userInfo;
                }
            })
            .error(function(data, status, headers, config) {
                var userInfo = {
                        isLogged: false,
                        username: '',
                        errorMsg: 'Server Error!'
                }
                return userInfo;
            });

        }
    }

});

Than I have a login controller that initiates the modal and handles the login attempts:

var loginController = function($scope, $http, $modal, userFactory) {
    $scope.userInfo = userFactory.getUserInfo();
    $scope.logged = $scope.userInfo.isLogged;
    $scope.open = function() {
        $scope.modalInstance = $modal.open({
        templateUrl: 'views/modal.html',
        controller: ModalInstanceCtrl,
        size: 'lg',
        resolve: {
            userInfo: function () {
                return $scope.userInfo;              
          }
        }
      });
    }
    $scope.login = function() {
        var loginObj = {
            username: $scope.username,
            password: $scope.password
        }
        var results = userFactory.login(loginObj);
        userFactory.loginNonce().then(function(data) {
            var nonce = data.data.nonce;
            loginObj.nonce = data.data.nonce;
            userFactory.login(loginObj).then(function(data) {
                if(data.data.error) {
                    $scope.errorMsg = data.data.error;
                } else {
                    $scope.ok();
                }
            }); 
        });
    }   
}

Here is the Modal Instance controller:

var ModalInstanceCtrl = function($scope, $modalInstance, $http, userFactory, userInfo) {
    $scope.userInfo = userFactory.getUserInfo(); 
    $scope.ok = function () {
        $modalInstance.close($scope.results);
        console.log(userInfo);
    };
    $scope.cancel = function () {
        $modalInstance.dismiss('cancel');
    };
} 

This is what the loginController partial looks like:

<div  id="main_bar" class="header" ng-controller="loginController">
  <ul class="nav nav-pills pull-right" >

    <li class="col-sm-3 col-md-3 col-lg-2 row  pull-right  userBlock" ng-show="logged"><div class="barAvatar" style="background-image: url({{ userAvatar }});"></div><div class="userName">{{ userFirstName }} {{ userLastName }} <span ng-click="logout()">Logout</span></div></li>
    <li ng-hide="logged" ><a ng-href="" ng-click="open()">Login</a></li>
    <li ng-hide="logged"><a ng-href="#/register">Signup</a></li>
  </ul>

</div>

This is the template partial for the login controller which displays the current user's information:

The login process works and the proper variables are set with the factory. However, I can't seem to get the updated userInfo object into the loginController's scope. I've used the console so I know the factory is working properly. I know this is probably a simple scope issue, but everything I have attempted has failed to work.

Upvotes: 0

Views: 259

Answers (2)

Tony
Tony

Reputation: 51

Because of scope inheritance I typically dot.notation all my scope variables. I'd have a $scope.user.info. That way you can read up the scope chain and use that variable. (complex reading here: https://github.com/angular/angular.js/wiki/Understanding-Scopes#javascript-prototypal-inheritance)

Upvotes: 1

Thomas Roch
Thomas Roch

Reputation: 1216

You need to add a success callback to your modal to be able to update userInfo on your LoginController scope. The first assignment to $scope.userInfo you have is only done when the controller gets instanciated.

$scope.open = function() {
    $scope.modalInstance = $modal.open({
    templateUrl: 'views/modal.html',
    controller: ModalInstanceCtrl,
    size: 'lg',
    resolve: {
        userInfo: function () {
            return $scope.userInfo;              
      }
    }
  }).result.then(function (userInfo) {
    $scope.userInfo = userInfo;
    // Or
    $scope.userInfo = userFactory.getUserInfo();
  });
}

Also in your modal you use both resolve and userFactory for obtaining the same information, you only need one of the two. And should your login function not be in the ModalInstanceCtrl?

Upvotes: 1

Related Questions