2

I'm working on my first non-trivial aura component for a lightning experience app, and I was trying to organize sub-component data using map attributes of essentially this pattern:

<aura:component>
  <aura:attribute name="fieldConfig" type="Map" />

  <c:myCustomComponent configAttr1="{!v.fieldConfig.attr1}" configAttr2="{v.fieldConfig.attr2}" etc... />
<aura:component>

Then, my sub component myCustomComponent has a controller which handles the valueChange event:

<aura:attribute name="configAttr1" type="String" access="public" />
<aura:handler name="change" value="{!v.configAttr1}" action="{!c.doSomething}" />

And my controller handles like this:

doSomething: function(cmp, evt, helper) {
  if (evt.getParam('oldValue') === evt.getParam('value')) {
    return;
  }

  //do config stuff
}

What I'm seeing is that when I use a property from a Map attribute and change the property, the evt.getParam('oldValue') and evt.getParam('value') contain a Proxy object, not a string as I'm expecting.

The frustrating thing is that I want to be able to maintain sub-component configuration in some kind of aggregation, especially when I have multiple of the same kindo of subcomponent, but the sub-component should be completely agnostic as to how its attributes are being set and managed by a parent.

Is there a better way to accomplish this? Am I misusing Map attributes? Do I really have to maintain separate attributes for every configuration attribute on a component, or bite the bullet and move all subcomponent configuration into a type "Map" attribute?

UPDATE

I can never wait for answers, so I did find a workaround. But I am still interested if there is an official way to do what I want.

Basically, instead of:

<c:myCustomComponent configAttr1="{!v.fieldConfig.attr1}" etc... />

I do

<c:myCustomComponent configAttr1="{!v.fieldConfig.attr1+''}" etc... />

The concatenation of the string makes the listeners always receive a primitive string value.

That said, that's a hack, not a great solution, as that means I have to remember to do that for every sub component attribute controlled from a changing Map attribute.

  • I have been struggling with this and can't believe this is still a problem. The aura framework frustrates me to no end, but this has to be the most egregious of issues I've run into. Additionally, your solution doesn't work for me. I need to retain the two-way binding that aura provides when passing attributes into a subcomponent. So, when your 'myCustomComponent' manipulates 'configAttr1' I need the parent component to get updated. This bug completely destroys the ability to do that. – captain_jim1 Jul 20 '18 at 5:28
  • Found a solution - don't use evt.getParam() to get the value or oldValue. Instead, access configAttr1 the old-fashioned way - componet.get("v.configAttr1")... this will have the correct value. – captain_jim1 Jul 20 '18 at 6:15
  • @captain_jim1 component.get('v.configAttr1') would return the current value, not the old value. Do you have a way of accessing the old value? – Cappielung Aug 22 '18 at 21:05
  • I think you might need to add another attribute to the component called "old value" and manually track it yourself. I can't think of another way around this. – captain_jim1 Aug 29 '18 at 19:39
  • Yup, that's all I can think of too. Thanks for your help! – Cappielung Aug 31 '18 at 13:48

Your Answer

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

Browse other questions tagged or ask your own question.