Cannot get textarea value in angularjs

Here is my plnkr: http://plnkr.co/edit/n8cRXwIpHJw3jUpL8PX5?p=preview You have to click on a li element and the form will appear. Enter a random string and hit 'add notice'. Instead of the textarea text you will get undefined.

Markup:

<ul>
    <li ng-repeat="ticket in tickets" ng-click="select(ticket)">
         {{ ticket.text }}
    </li>
</ul>
<div ui-if="selectedTicket != null">
     <form ng-submit="createNotice(selectedTicket)">
        <textarea ng-model="noticeText"></textarea>
        <button type="submit">add notice</button>
    </form>
</div>

JS part:

$scope.createNotice = function(ticket){
   alert($scope.noticeText);
}

returns 'undefined'. I noticed that this does not work when using ui-if of angular-ui. Any ideas why this does not work? How to fix it?

Your problem lies in the ui-if part. It seems that angular-ui creates a new scope for anything within that directive so in order to access the parent scope, you must do something like this:

<textarea ng-model="$parent.noticeText"></textarea>

Instead of

<textarea ng-model="noticeText"></textarea>

This issue happened to me while not using the ng-if directive on elements surrounding the textarea element. While the solution of Mathew is correct, the reason seems to be another. Searching for that issue points to this post, so I decided to share this.

If you look at the AngularJS documentation here https://docs.angularjs.org/api/ng/directive/textarea , you can see that Angular adds its own directive called <textarea> that "overrides" the default HTML textarea element. This is the new scope that causes the whole mess.

If you have a variable like

$scope.myText = 'Dummy text';

in your controller and bind that to the textarea element like this

<textarea ng-model="myText"></textarea>

AngularJS will look for that variable in the scope of the directive. It is not there and thus he walks down to $parent. The variable is present there and the text is inserted into the textarea. When changing the text in the textarea, Angular does NOT change the parent's variable. Instead it creates a new variable in the directive's scope and thus the original variable is not updated. If you bind the textarea to the parent's variable, as suggested by Mathew, Angular will always bind to the correct variable and the issue is gone.

<textarea ng-model="$parent.myText"></textarea>

Hope this will clear things up for other people coming to this question and and think "WTF, I am not using ng-if or any other directive in my case!" like I did when I first landed here ;)

I'm not supposed to ask for help or clarification, but stack overflow won't let me add comments to either of the other answers so I continue here.

I had the same problem and Matthew Berg's answer got me where I needed to go. What I find bewildering is that I couldn't find this business about $parent in the model name documented anywhere. I was confused that when I added $scope.mytextarea = "XYZ" the text appeared in the textarea and when I changed the text, I found that $scope.mytextarea constantly had "XYZ" in it. After applying your fix, $scope.mytextarea had what I typed on the page. But now I'm back to being a little confused that the $scope.mytextarea = "XYZ"; still set the textarea.

Just what is going on with this and where are docs? I note that the W3 schools gives a demo of this, but the example doesn't actually show any retrieved text nor is there mention of $parent.

It is, indeed, ui-if that creates the problem. Angular if directives destroy and recreate portions of the dom tree based on the expression. This is was creates the new scope and not the textarea directive as marandus suggested.

Here's a post on the differences between ngIf and ngShow that describes this well—what is the difference between ng-if and ng-show/ng-hide.