15

I'm using ionic and I have the following view:

<ion-view hide-nav-bar="true" ng-controller="loginController" class="login-view">
  <ion-content class="padding">

    <div class="row row-center">
      <div class="col">

        <div id="logo"></div>

        <form>
          <div class="list">
            <label class="item item-input">
              <input type="text" placeholder="Membership No" ng-model="membershipNo">
            </label>
            <label class="item item-input">
              <input type="password" placeholder="Password" ng-model="password">
            </label>
          </div>

          <button class="button button-block button-positive button-login" ng-click="login()">
            Login
          </button>
        </form>

      </div>
    </div>

  </ion-content>
</ion-view>

And my controller:

app.controller('loginController', ['$scope', '$localstorage',
    function($scope, $localstorage) {

        $scope.membershipNo;
        $scope.password;

        $scope.login = function () {
            console.log("User logged in with membership no: " + $scope.membershipNo +
    "\n and password: " + $scope.password);
        }

    }
]);

What I don't understand, is that when I click the button, the login function is called correctly. Also, if in the controller I go and set $scope.membershipNo to something like "Banana Pancake", the view actually updates.

Yet when the login function actually runs, is says that membershipNo and password are undefined. I'm fairly new to Angular and Ionic so I know this is probably some n00b mistake...

9
  • 5
    You're binding to a primitive. Don't do that. codelord.net/2014/05/10/… (Essentially, the value of membershipNo is being passed by value, so what's being changed is not the reference in the controller. Create an Object, something like $scope.user = {} and pass that ng-model="user.membershipNo", otherwise Angular cannot send data back to the controller...) Commented Aug 13, 2015 at 12:47
  • possible duplicate of Ng-model does not update controller value Commented Aug 13, 2015 at 12:48
  • 2
    What @DRobinson said. You can avoid that by using controllerAs-syntax, also making your code more elegant and future-proof in the process :-) Commented Aug 13, 2015 at 12:51
  • 1
    @Rahil that only works if nothing between the ngController and the ngModel creates a new scope. It's very bad practice. You really want "dots" in your ngModel, every time. Always. stackoverflow.com/a/17186640/624590 (It also won't work for Dean because ionContent creates a scope.) Commented Aug 13, 2015 at 12:58
  • 1
    I once owned a tele-scope as a kid but it never really could see very far. It did look cool though standing in my room. Commented Aug 13, 2015 at 13:01

5 Answers 5

43

I had exact the same issue recently and that's probably a solution: https://stackoverflow.com/a/22768720/552936

Modified quote:

"If you use ng-model, you have to have a dot in there."
Make your model point to an object.property and you'll be good to go.

Controller

$scope.formData = {};
$scope.login = function () {
  console.log("User logged in with membership no: " + $scope.formData.membershipNo +
  "\n and password: " + $scope.formData.password);
 }

Template

<input type="text" placeholder="Membership No" ng-model="formData.membershipNo">
<input type="password" placeholder="Password" ng-model="formData.password">
Sign up to request clarification or add additional context in comments.

3 Comments

Though this will resolve the issue, it doesn't really provide an answer why it failed in the first place.
Just like @DRobinson said and like your example above shows, I took membershipNo and password and wrapped them in a 'credentials' object and now magically everything works.. but WHY!?
I am also curious as to the why of this. I have other variables that work fine not being in an object
3

Please check this code This is worked for me:

<div class="row row-center">
  <div class="col">

    <div id="logo"></div>

    <form>
      <div class="list">
        <label class="item item-input">
          <input type="text" placeholder="Membership No" ng-model="data.membershipNo">
        </label>
        <label class="item item-input">
          <input type="password" placeholder="Password" ng-model="data.password">
        </label>
      </div>

      <button class="button button-block button-positive button-login" ng-click="login()">
        Login
      </button>
    </form>

  </div>
</div>

and in your-controller:

app.controller('loginController', ['$scope',
  function($scope) {
    $scope.data={};
  $scope.login = function () {
    console.log("User logged in with membership no: " + $scope.data.membershipNo +
    "\n and password: " + $scope.data.password);
  }

}]);

Comments

2

You need to define your $scope variables like this in your controller:

$scope.membershipNo = '';
$scope.password = '';

So your controller would look like:

app.controller('loginController', ['$scope', '$localstorage',
  function($scope, $localstorage) {

  $scope.membershipNo = '';
  $scope.password = '';
  $scope.login = function () {
    console.log("User logged in with membership no: " + $scope.membershipNo +
    "\n and password: " + $scope.password);
  }

}]);

1 Comment

I did try that, then the function prints out just blank values and not actually what the user entered...?
1

Hey Jean,Have a look of it your code is working here

       <ion-view ng-app="app" hide-nav-bar="true" ng-controller="loginController" class="login-view">
      <ion-content class="padding">

        <div class="row row-center">
          <div class="col">

            <div id="logo"></div>

            <form>
              <div class="list">
                <label class="item item-input">
                  <input type="text" placeholder="Membership No" ng-model="membershipNo">
                </label>
                <label class="item item-input">
                  <input type="password" placeholder="Password" ng-model="password">
                </label>
              </div>

              <button class="button button-block button-positive button-login" ng-click="login()">
                Login
              </button>
            </form>

          </div>
        </div>

      </ion-content>
    </ion-view> 


var app= angular.module("app",[]);
    app.controller('loginController', ['$scope', 
      function($scope, $localstorage) {

      $scope.membershipNo;
      $scope.password;
      $scope.login = function () {
        alert("User logged in with membership no: " + ($scope.membershipNo || '') +
        "\n and password: " + ($scope.password || ''));
      }

    }]);

2 Comments

could you add an explanation helping the "asker" to understand what you've done and why - so that we can all learn from it
Hi Ry8806, It's a concept of typical inheritance. As the @mbajur make in his example by making a object of it. It is pattern in javascript that angularjs used. If the heirarchies used in you code like realtion between child scopes & parent scopes are maintained properly then there should be no issues in that. Else you get these type of issue in angularjs of losing the scope properties value. But if you can see i just make a simple controller then it's work properly. And i don't know the exact thing what jean wants to do. But in code snippet he added is having no issue.
0
$scope.user = {};
$scope.submitForm = function (isValid) {
   if (($scope.user.name || '').length > 0){ //Code }
}

Comments