4

I have a login form but for some reason the data is not being binded between the HTML and the controller. This is my code:

home.html

<div ng-if="loggedIn">
    <h2>Welcome!</h2>
    <p>Some other welcome content...</p>
</div>

<form ng-if="!loggedIn">
    <input type="text" placeholder="Username" ng-model="username">
    <input type="password" placeholder="Password" ng-model="password">
    <button type="submit" data-ng-click="login()">Login</button>
</form>

Note: labels, classes and ids ommited for brevity.

controller.js

myapp.controller('HomeController', ['$scope', '$log', function(scope, log) {
    scope.loggedIn = false;
    // ADDED CODE HERE

    scope.login = function() {
        // Dummy validation
        if(scope.username == 'admin' && scope.password == 'admin') {
            scope.loggedIn = true;
        };
        log.log('username: ' + scope.nombreUsuario);
        log.log('password: ' + scope.password);
        log.log('is logged in: ' + scope.loggedIn);
    };
}]);

config.js

myapp.config(['$locationProvider', '$routeProvider', function(locationProvider, routeProvider) {
    // Remove default '!' from URL
    locationProvider.hashPrefix('');

    routeProvider
    .when('/', {
        templateUrl: 'templates/home.html',
        controller: 'HomeController'
    })
    // ... some other .when ...
    .otherwise({
        redirectTo: '/'
    });
}]);

When I execute this, the console output of the login function is

username: undefined
password: undefined
is logged in: false

However, if I add the following to the controller in the //ADDED CODE HERE section

scope.username = 'admin';
scope.password = 'admin';

the console gives me the following:

username: admin
password: admin
is logged in: true

i.e. it's working correctly. So the question is: why my view (ng-model="...") doesn't bind to the controller's scope? what am I missing here?

Thanks in advance for your answer.

4
  • Where is your ng-controller="HomeController" placed? Commented May 19, 2017 at 15:46
  • It's in the myapp.config section, I can tell for sure that it's working correctly Commented May 19, 2017 at 15:48
  • Could you add more codes? Let us see in which way your controller is binded to your view. Commented May 19, 2017 at 15:50
  • @lin, please check the update. Let me know if you need more info. Thanks for your comments Commented May 19, 2017 at 16:32

2 Answers 2

3

Just access the $parent scope $parent.username, $parent.password and you will be fine like in this demo fiddle.

Some directives like ng-if does create a child scope so you need to access the parent scope. (Thx @FrankModica). E.g. if you are using ng-show or ng-hideyou dont need to access a $parent scope (Demo fiddle which uses ng-show).

<form ng-if="!loggedIn">
    <input type="text" placeholder="Username" ng-model="$parent.username">
    <input type="password" placeholder="Password" ng-model="$parent.password">
    <button type="submit" data-ng-click="login()">Login</button>
</form>
Sign up to request clarification or add additional context in comments.

3 Comments

This will work, but is not recommended because it is brittle. If the page is updated and new scopes are added you can run into issues.
Great!, worked perfectly. But why do I need to access the parent scope? (what's the parent scope anyway? It's the first time I need to use it) Thank you so much
I'll take into account the posible issue you mention. I've seen now the explanation in the edit. Thanks again
2

Try binding to an object:

$scope.myForm = {
    userName: '',
    password: '',
    // ...
};

<input type="text" placeholder="Username" ng-model="myForm.username">

Because of prototypal inheritance, ng-model is initially reading from the parent scope (your controller). But as soon as the user types, ng-model ends up writing to the child scope created by ng-if, which inherits from the parent scope. If you bind to an object (not a primitive), you can be sure you will be reading and writing from the same place.

Comments

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.