JohnWick
JohnWick

Reputation: 5149

AngularJS ng-model not working?

I have this index.html which has a navbar in the which is seen on all pages of my single page application. The navbars container div is using the ng-controller="LoginCtrl" value, so I will also include that controller from my angular application (app.js)

For some reason, the variables username and password which are bound via ng-model are showing as undefined when doLogin() is called via ng-click directive? That is after I type values into the text boxes that are bound to my controllers variables.

index.html

<!DOCTYPE html>

<html ng-app="myApp">
<head>

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
    <link href="stylesheet.css" rel="stylesheet">

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular-route.min.js"></script>
    <base href="/">

    <script src="https://cdnjs.cloudflare.com/ajax/libs/ngStorage/0.3.9/ngStorage.js"></script>
    <script src="https://cdn.socket.io/socket.io-1.3.5.js"></script>

</head>
<body>

    <div ng-controller="LoginCtrl">
        <nav class="navbar navbar-default">
            <div class="container">
                <div class="navbar-header">
                    <a class="navbar-brand" href="#">TriviaAttack!</a>
                </div>
                <div id="navbar" class="navbar-collapse collapse">
                    <form ng-if="!loggedIn" id="loginForm" class="navbar-form navbar-right">
                        <div class="form-group">
                            <input type="text" placeholder="Email" class="form-control" ng-model="username">
                        </div>
                        <div class="form-group">
                            <input type="text" placeholder="Password" class="form-control" ng-model="password">
                        </div>
                        <div class="form-group">
                            <button type="submit" class="btn btn-success" ng-click="doLogin()">Sign In</button>
                        </div>                  
                    </form>
                </div>
            </div>
        </nav>
        <div ng-view></div>
    </div>

    <script src="./app/app.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js">

</body>
</html>

app.js

...
myApp.controller('LoginCtrl', function($rootScope, $location, AuthService, AuthToken) {

    $rootScope.doLogin = function() {
        console.log($rootScope.username);
        console.log($rootScope.password);
    }

});
...

Upvotes: 2

Views: 4027

Answers (4)

JohnWick
JohnWick

Reputation: 5149

I found the answer to my own question after some frustration. Adding username and password arguments to my doLogin() function, then using the directive ng-click="doLogin(user.name, user.pass)" works as I wanted. No clue why it wasn't working the way I was trying, but oh well.

Upvotes: 1

nidhin
nidhin

Reputation: 439

use $scope instead of $rootScope for getting the ng-model in controller.

Upvotes: 1

kavinhuh
kavinhuh

Reputation: 739

An inputModel primitive property will be created on that ng-controller's scope when you type into the text field. input model is generated in the current scope, not the rootScope.

var app = angular.module('myApp', []);
app.controller('LoginCtrl', function($scope, $http) {
  $scope.doLogin = function() {
        console.log($scope.username);
        console.log($scope.password);
    }
});

Check it out on Plunker

Upvotes: 2

Md Hasan Ibrahim
Md Hasan Ibrahim

Reputation: 1898

Use model rather than using primitive types.

You should use $rootScope.user.name (ng-model will be user.name) rather than using $rootScope.username and $rootScope.user.password(ng-model will be user.password) instead of $rootScope.password

This problem actually happens for javascript's prototypical model. And if you want to know it's applicability in angularjs, you can go through this article. This will definitely help :)

Edit: As you are running into problem making that code work, I've made a working copy of your code. Please have a look at it:

<!DOCTYPE html>

<html ng-app="myApp">
<head>

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
    <link href="stylesheet.css" rel="stylesheet">

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular-route.min.js"></script>
    <base href="/">

    <script src="https://cdnjs.cloudflare.com/ajax/libs/ngStorage/0.3.9/ngStorage.js"></script>
    <script src="https://cdn.socket.io/socket.io-1.3.5.js"></script>

</head>
<body>

    <div ng-controller="LoginCtrl">
        <nav class="navbar navbar-default">
            <div class="container">
                <div class="navbar-header">
                    <a class="navbar-brand" href="#">TriviaAttack!</a>
                </div>
                <div id="navbar" class="navbar-collapse collapse">
                    <form ng-if="!loggedIn" id="loginForm" class="navbar-form navbar-right">
                        <div class="form-group">
                            <input type="text" placeholder="Email" class="form-control" ng-model="user.name">
                        </div>
                        <div class="form-group">
                            <input type="text" placeholder="Password" class="form-control" ng-model="user.password">
                        </div>
                        <div class="form-group">
                            <button type="submit" class="btn btn-success" ng-click="doLogin()">Sign In</button>
                        </div>
                    </form>
                </div>
            </div>
        </nav>
        <div ng-view></div>
    </div>

    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>

</body>
</html>

<script>
    var myApp = angular.module("myApp", []);
    myApp.controller('LoginCtrl', function ($scope, $location) {

        $scope.user = { name: "", password: "" };
        $scope.doLogin = function () {
            console.log($scope.user.name);
            console.log($scope.user.password);
        }

    });
</script>

Upvotes: 1

Related Questions