20

I am having some "problems" reading an ng-model from the controller.

I want to do this:

<input type="text" ng-model="code">
<button ng-click="setCode()">Login</button>

And in my controller access that variable like this:

 $scope.setCode = function(){
    alert($scope.code);
  }

That is what I want to do but my code variable is undefined.

I found 2 ways to get this to work:

1) Passing the variable as an argument

<input type="text" ng-model="code">
<button ng-click="setCode(code)">Login</button>

and:

$scope.setCode = function(code){
    alert(code);
  }

2) Declaring my variable as an object

<input type="text" ng-model="code.text">
<button ng-click="setCode()">Login</button>

and:

$scope.code = {text: 'foo'};

[...]

$scope.setCode = function(){
    console.log($scope.code);
  }

(I prefer the second one)

But I am a little confused about what I should do. It's ok to declare my ng-models like objects? I have to declare ALL my models like objects?


EDIT: Here is a Plnkr of the problem

In this example (I am using the Ionic framework), I declare a variable code with the value test, when I change the model in the input and press the Start button, in theory I have to see in an alert the new value of the model. But what I see is the old one.

Thanks!

Mati Tucci
  • 2,826
  • 5
  • 28
  • 40
  • The first example should work fine. – tymeJV Mar 31 '14 at 13:27
  • Make sure that controller scope and the scope on which the ng-model is being set are same, directives like ng-if and ng-repeat create their own scope. Otherwise your first example should be working fine. – Designing the Code Mar 31 '14 at 14:31
  • 1
    @DesigningtheCode oh thx for pointing out on ng-if, i was hiding email field this way and was wondering what the heck... – Max Yari Jul 01 '15 at 14:03

3 Answers3

10

I fixed your plnkr example using object model instead of primitive type.

$scope.model = {};
$scope.model.code = "test";

$scope.setCode = function(){
    alert($scope.model.code);
}

See the plnkr.

xi.lin
  • 3,326
  • 2
  • 31
  • 57
  • Thank you! I had a similar problem as OP and your method solved it. Do you have any idea why OP's code didn't work in the plnkr he shared as a comment in Erik's answer? – Tad Donaghe Sep 11 '14 at 22:37
  • @TadDonaghe You can check the discussion [here](http://stackoverflow.com/questions/17178943/does-my-ng-model-really-need-to-have-a-dot-to-avoid-child-scope-problems). I'm not familiar with ionic-framework, but i think the `label` and `button` tag will introduce new scope here so that we can only use a non-primitive object to pass reference. – xi.lin Sep 15 '14 at 09:57
7

Your first example is working, here is a plunkr.

If you hit the button without entering any text into the input field you get an alert undefined. $scope.code gets defined the moment you enter something to its bound field ng-model="code".

You could initialize it to a default in your controller too:

$scope.code = 'my default value';
Johanna Larsson
  • 10,531
  • 6
  • 39
  • 50
nilsK
  • 4,323
  • 2
  • 26
  • 40
  • I already tried it, but is the same. Here is a [Plnkr](http://plnkr.co/edit/X8CpI0DlHTgSgxHeuptw?p=preview) of what is going on. Thanks! – Mati Tucci Apr 01 '14 at 16:20
0

Ionic's directive will create the new scope, if you want to use the code object in controller directly, you must set ng-controller to ion-content in your HTML page, not to the router state.

Liam Mazy
  • 390
  • 3
  • 15