Unable to get textarea value in angularjs

Here is my plnkr: http://plnkr.co/edit/n8cRXwIpHJw3jUpL8PX5?p=preview You need to click the li element and a form will appear. Enter a random line and click "add notification." Instead of textarea you 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 angular -ui. Any ideas why this is not working? How to fix it?

+50
angularjs angular-ui
Apr 29 '13 at 17:13
source share
4 answers

Your problem is part of the user interface. Angular-ui creates a new scope for anything in this directive, so to access the parent scope you have to do something like this:

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

Instead

 <textarea ng-model="noticeText"></textarea> 
+93
Apr 29 '13 at 17:27
source share

This problem happened to me without applying the ng-if directive to elements surrounding the textarea element. Although Matthew's decision is correct, the reason seems different. A search for this problem points to this message, so I decided to share this.

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

If you have a variable like

 $scope.myText = 'Dummy text'; 

in your controller and bind it to a textarea element like this

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

AngularJS will look for this variable in the scope of the directive. It is not, and therefore it approaches $ parent. The variable is present there, and the text is inserted into textarea . When changing text in textarea , Angular does NOT change the parent variable. Instead, it creates a new variable in the scope of the directive and, therefore, the original variable is not updated. If you bind textarea to the parent variable, as suggested by Matthew, Angular will always bind to the correct variable, and the problem will disappear.

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

I hope this clarifies the situation for other people coming to this question and think: "WTF, I do not use ng-if or any other directive in my case!" as I did when I first landed here;)

Update: use controller syntax -

I wanted to add this long before that, but I did not find time for this. This is a modern style of building controllers and should be used instead of the above $parent . Read on to find out how and why.

Since AngularJS 1.2 allows you to refer to the controller object directly, instead of using the $scope object. This can be achieved using this syntax in the HTML markup:

 <div ng-controller="MyController as myc"> [...] </div> 

Popular routing modules (such as the UI Router) provide similar properties for their states. For the UI Router, you use the following in determining your status:

 [...] controller: "MyController", controllerAs: "myc", [...] 

This helps us bypass the problem with nested or incorrectly addressed areas. The above example will be constructed in this way. The first part is JavaScript. Right ahead, you just don’t use the $scope link to set your text, just use this to attach the property directly to the controller object.

 angular.module('myApp').controller('MyController', function () { this.myText = 'Dummy text'; }); 

The markup for textarea with controller-as syntax would look like this:

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

This is the most effective way to do such things today, because it solves the problem using nested areas, forcing us to calculate how many layers we are at a certain point. Using several nested directives inside elements with the ng-controller directive could lead to something similar when using the old method of referencing areas. And nobody wants to do this all day!

 <textarea ng-model="$parent.$parent.$parent.$parent.myText"></textarea> 
+63
Nov 20 '14 at 13:30
source share

Bind a text box to a variable scope , and not directly to the scope variable:

controller:

 $scope.notice = {text: ""} 

template:

 <textarea ng-model="notice.text"></textarea> 
+25
Oct 25 '15 at 8:26
source share

This, indeed, ui-if poses a problem. Angular, if directives destroy and recreate parts of the dom tree based on an expression. This created a new scope, rather than textarea directives, as the marandus suggested.

Here is a post on the differences between ngIf and ngShow that describe it well what is the difference between ng-if and ng-show / ng-hide .

+2
Apr 13 '15 at 5:42
source share



All Articles