Error: [ngModel:nonassign] Expression is non-assignable
Asked Answered
R

3

21

Trying to display a columnvalue from a gridcollection based on another value in that same row. The user can select/change values in a modal which contains a grid with values. When the modal closes the values are passed back. At that moment I would like to set a value for 'Also known as':

html:

 Also known as: <input type="text" `ng-model="displayValue(displayNameData[0].show,displayNameData[0].value)">`

I created a function on scope to select the value only when the 'show' value is true:

$scope.displayValue = function (show, val) {
    if (show) {
        return val;
    }
    else {
        return '';
    }
}

However when I close the modal I get an error:

Error: [ngModel:nonassign] Expression 'displayValue(displayNameData[0].show,displayNameData[0].value)' is non-assignable. 

plnkr reference:http://plnkr.co/edit/UoQHYwAxwdvX0qx7JFVW?p=preview

Requisition answered 12/6, 2014 at 6:22 Comment(1)
Just for information. This error will occur in case of model names without camel case as well. ie; ng-model="employee-name" will through error, where as ng-model="employeeName" don't have a problem.Bushcraft
V
16

As HackedByChinese mentioned, you can't bind ng-model to a function, so try like this:

<input type="text" ng-if="displayNameData[0].show"
                   ng-model="displayNameData[0].value">

Or if you want this control to be visible you can create directive, add function to $parsers that will set empty value according to show:

    angular.module('yourModule').directive('bindIf', function() {
        return {
            restrict: 'A',
            require: 'ngModel',

            link: function(scope, element, attrs, ngModel) {
                function parser(value) {
                    var show = scope.$eval(attrs.bindIf);
                    return show ? value: '';
                }

                ngModel.$parsers.push(parser);
            }
        };
    });

HTML:

<input type="text" bind-if="displayNameData[0].show"
                   ng-model="displayNameData[0].value">
Vernitavernoleninsk answered 12/6, 2014 at 6:37 Comment(2)
Correct, but it'd be helpful to point out in your answer that you can't bind ng-model to a function.Bleach
@HackedByChinese thanks, I'll add your note to answerVernitavernoleninsk
S
42

Using ng-value instead of ng-model worked for me.

Stateless answered 7/8, 2015 at 22:12 Comment(3)
ng-init might help, if your getting that error in other situations.Gilmagilman
In my case, I had to use both ng-value and ng-model, the last one for persist data to the model, whereas ng-value to display and filter data.Pentheas
I had an issue with formatting values in ng-model bottom line you can't do that. I attempted to set formatting on value in html for the form input field but it was getting over wrote by ng-model. Using ng-value fixed the problem. Thanks @PentheasBalmacaan
V
16

As HackedByChinese mentioned, you can't bind ng-model to a function, so try like this:

<input type="text" ng-if="displayNameData[0].show"
                   ng-model="displayNameData[0].value">

Or if you want this control to be visible you can create directive, add function to $parsers that will set empty value according to show:

    angular.module('yourModule').directive('bindIf', function() {
        return {
            restrict: 'A',
            require: 'ngModel',

            link: function(scope, element, attrs, ngModel) {
                function parser(value) {
                    var show = scope.$eval(attrs.bindIf);
                    return show ? value: '';
                }

                ngModel.$parsers.push(parser);
            }
        };
    });

HTML:

<input type="text" bind-if="displayNameData[0].show"
                   ng-model="displayNameData[0].value">
Vernitavernoleninsk answered 12/6, 2014 at 6:37 Comment(2)
Correct, but it'd be helpful to point out in your answer that you can't bind ng-model to a function.Bleach
@HackedByChinese thanks, I'll add your note to answerVernitavernoleninsk
W
9

You can bind ng-model to function

Binding to a getter/setter
Sometimes it's helpful to bind ngModel to a getter/setter function. A getter/setter is a function that returns a representation of the model when called with zero arguments, and sets the internal state of a model when called with an argument. It's sometimes useful to use this for models that have an internal representation that's different from what the model exposes to the view.

index.html

<div ng-controller="ExampleController">
  <form name="userForm">
    <label>Name:
      <input type="text" name="userName"
             ng-model="user.name"
             ng-model-options="{ getterSetter: true }" />
    </label>
  </form>
  <pre>user.name = <span ng-bind="user.name()"></span></pre>
</div>

app.js

angular.module('getterSetterExample', [])
.controller('ExampleController', ['$scope', function($scope) {
  var _name = 'Brian';
  $scope.user = {
    name: function(newName) {
     // Note that newName can be undefined for two reasons:
     // 1. Because it is called as a getter and thus called with no arguments
     // 2. Because the property should actually be set to undefined. This happens e.g. if the
     //    input is invalid
     return arguments.length ? (_name = newName) : _name;
    }
  };
}]);
Wellpreserved answered 28/9, 2015 at 19:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.