3

I came across this occurrence while developing a lightning component. I'm trying to bind a checkbox value to the inverse of the value of the NetworkMember.PreferencesDisableAllFeedsEmail field. But the value does not change when the checkbox is clicked/changed. Here's a code sample:

<aura:attribute name='member' type='NetworkMember'/>

<div class="slds-order--1 slds-medium-order--1 slds-large-order--1">
    <ui:inputCheckbox value='{!!v.member.PreferencesDisableAllFeedsEmail}' change='{!c.allPrefDisabled}'/>
    <label class="slds-form-element__label">Recieve Emails</label>
</div>

When I do this (note the ! in the value attr), the field's value never changes from it's original state, despite changing it in the UI. However, if I remove the ! like so:

<aura:attribute name='member' type='NetworkMember'/>

<div class="slds-order--1 slds-medium-order--1 slds-large-order--1">
    <ui:inputCheckbox value='{!v.member.PreferencesDisableAllFeedsEmail}' change='{!c.allPrefDisabled}'/>
    <label class="slds-form-element__label">Recieve Emails</label>
</div>

The value is updated accordingly. Of course, I could change the label to Disable Emails as a workaround but I can't imagine that this is expected behavior. Has anyone observed this before and is this a platform bug, or is there some reasoning for this?

Any insight is appreciated. Thanks!

Edit: I also tried using the lightning function not listed here: docs as opposed to the ! and observed the same behavior.

3
  • When you use the evaluation operator you may be loosing the binding to the field
    – Eric
    Dec 22 '16 at 21:10
  • @Eric I'd assume something along those lines is happening. Although I would think there would be a way to get the value reflected in the UI either through event.getSource().get('v.value') or component.find('AURA_ID').get('v.value') or some similar mechanism but those values never change from their initial state. I thought it was odd because I never had this issue using Visualforce. Dec 22 '16 at 21:19
  • 1
    I have said something similar with process builder. "Never had these issues with workflows" lol. It will get there just may take some time
    – Eric
    Dec 22 '16 at 21:22
4

When you add the negation to the value property it turns the expression to a FunctionCallValue. Since it is no longer directly mapped to an attribute (as it is with the single !), clicking the checkbox no longer updates the original attribute. Imagine if instead of a simple negation there was a more complicated expression like value="{!v.myAttr.foo == 'meep'}". The framework doesn't know what to set back to this expression when the checkbox is clicked, so it ignores it.

In fact, if you go to Setup --> Lightning Components and check the "Enable Debug Mode" checkbox, you'll see a similar error in the console:

aura_dev.js:3977 AttributeSet.set(): unable to override the value for 'value=function (cmp, fn) { return !(cmp.get("v.myAttr.foo")); }'. FunctionCallValues declared in markup are constant.

There's probably a better way to handle this, but one workaround is to create a new attribute that is bound to the ui:inputCheckbox value and then in the change handler update v.member.PreferencesDisableAllFeedsEmail. Here's a simplified example:

Markup:

<aura:attribute name="checkboxValue" type="Boolean" default="false"/>
<ui:inputCheckbox value='{!v.checkboxValue}' change='{!c.changed}'/>

Controller:

changed: function(cmp) {
    var val = cmp.get("v.checkboxValue");
    cmp.set("v.member.PreferencesDisableAllFeedsEmail", !val);
}

In your case you'd probably want to set the initial value of checkboxValue to the negation of member.PreferencesDisableAllFeedsEmail in the init handler (or similar).

2
  • Thanks for the explanation here. Out of curiosity, is it on the road map to support this type of binding? Dec 28 '16 at 19:44
  • 1
    No, there are no plans to add bindings to FunctionCallValue's like in your example. Dec 28 '16 at 20:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.