Passing dynamic value with single quote as a ng-true-value expression fails

angularjs

Solution

The short version, `ng-true-val` expects a constant and is being passed the following expression as a parameter: `'Customer didn't understand'` for evaluation, which is malformed because of un-terminated single quote.

The simple (but somewhat ugly) approach would be to replace `'` with `\'` in the View (this doesn't change the actual value - just encodes it):

<input type="checkbox" ng-model="foo"
       ng-true-value="'{{trueVal.replace('\'', '\\\'')}}'"
       ng-false-value="null">

The better approach is probably using `ng-change`:

<input type="checkbox" ng-model="t"
       ng-change="foo = t ? trueVal : null">

Longer version

Under the covers `ng-true-value` calls `$parse` service: `var parseFn = $parse(expression)`, and expects `parseFn.constant === true`. The latter is only true if the expression is a constant:

expression = 'string';      // string literal
expression = '5'            // number literal
expression = {v: 'string'}  // object literal with a constant
expression = 'foo' + 'bar'; // expression that evaluates to a constant

In your case you need to take the variable `trueVal`, interpolate it to a value `{{trueVal}}`, to become part of an expression `'{{trueVal}}'` that ultimately will be evaluated as explained above.

This is why substitution of `'` works to `\'`, because it escapes the singles quotes as if you have written the expression directly:

ng-true-value="'Customer didn\'t understand'"

If you are certain that you won't have double quotes (`"`) in your values for `options`, you could also simply reverse the order of quotes without the need to do `replace`:

ng-true-value='"{{trueVal}}"`

This will, of course, fail for the same reason if `trueVal` value had double quotes: `something with "quotes"`.

Problem

I have my checkbox input that sets the "true" value dynamically based on a variable `trueVal`, which is a string. ``` <input ng-model="foo" ng-true-value="'{{trueVal}}'"> ``` For example, for `trueVal = "something"`, `foo === "something"` when the checkbox is checked. This works except in the case when `trueVal` equals to a string with a single quote in it: `Customer didn't understand`. In this case, there is an error: Error: [$parse:lexerr] Lexer Error: Unterminated quote at columns 27-28 ['] in expression ['Customer didn't understand']. I can't strip the single quotes because the string should be set as-is to `foo`. Broader context: I'm creating a group of checkboxes based on a list of `options` that I get from the back-end: ``` <div ng-repeat="(key,option) in options"> <input type="checkbox" ng-model="foo[key]" ng-true-value="'{{option.trueVal}}'" ng-false-value="null"> </div> ``` So, given: ``` options = { 0: {trueVal: "Customer was late"}, 1: {trueVal: "Customer didn't understand"} }; ``` I expect to see: ``` foo = { 1: "Customer didn't understand" }; ``` if the second box is checked.

Original source