AngularJS directive: Expression 'undefined' used with directive ... is non-assignable
Solution 1
You were close.. The main problem is changing a scope variable inside an event that angular doesn't know about. When that event occurs, you have to tell angular that something changed by using scope.$apply
.
$el.on('keyup', function() {
scope.$apply( function() {
scope.caretPosition = $el.caret();
});
});
For the questions:
- yes, I don't think there's a way around having to write a directive for this.
- in this case, it seems fine.
- not sure, there are no problems in the jsfiddle. It sounds like you're setting
carat="something"
somewhere? check to make sure the html is the same as what's in the fiddle. - same as 3
Also note that if you click and move the caret, it won't update because it's only listening for keyup.
Solution 2
My solution was harder to find out here, but easier to implement. I had to change it to the equivalent of;
scope: {caretPosition: '=?'},
(Note that the question mark makes the attribute optional. Prior to 1.5 this apparently wasn't required.)
Related videos on Youtube
poshest
Updated on July 09, 2022Comments
-
poshest almost 2 years
I'm a 2 week old Angular noob, and I've been attempting my first ever directive for over a day now. :P I've read this and this, which seem good directives introductions and a bunch of Stackoverflow answers, but I can't get this working.
<div ng-app="App" ng-controller="Main"> <textarea caret caret-position="uiState.caretPosition"></textarea> {{uiState.caretPosition}} </div>
and
angular.module('App', []) .controller('Main', ['$scope', function ($scope) { $scope.uiState = {}; $scope.uiState.caretPosition = 0; }]) .directive('caret', function() { return { restrict: 'A', scope: {caretPosition: '='}, link: function(scope, element, attrs) { var $el = angular.element(element); $el.on('keyup', function() { scope.caretPosition = $el.caret(); }); } }; });
Fiddle is here. I'm basically trying to get the caret position within a textbox. I'm using this jQuery plugin in the fiddle (source of the .caret() method, which should just return a number).
My questions are
- Do I even need a directive here? Ben Nadel says the best directives are the ones you don't have to write (amen to that!)
- If yes, is this the right way to go about the directive? Ie isolated scope with two-way bound variable?
- If yes, when I run this code locally, I keep getting the error
Expression 'undefined' used with directive 'caret' is non-assignable!
. I've read the doc and as far as I can tell I've followed instructions for how to fix to no avail. - BONUS: Why in jsfiddle do I get no such error. The fiddle just fails silently. What's with that?
Thanks!
-
smurtagh almost 7 yearsI think @Lois's answer is more common for the angular problem in the title.
-
poshest over 10 yearsDamn, and I had already tried the scope.$apply based on this excellent article too! link (slider example). Must have had something else wrong at the time. Your answer fixes the fiddle, so accepted! I was still getting the error in my app. It was indeed because the fiddle didn't match my code! :P There were a two textareas defined in my code and one was missing the caret-position attribute. A case of many concurrent errors, and not knowing which one the error msg is describing!
-
poshest over 10 yearsSubmitted request to update the Angular docs