2

I'm trying to set the 'Rating' field on an account record using the client-side controller. The account record has been returned from the server. Here's my approach.

Application:

<aura:application controller="SetFieldTestCtlr">
    <aura:handler name="init" value="{!this}" action="{!c.init}" />
    <!--type=Object does not fix the problem-->
    <aura:attribute type="Account" name="acc"/>
    acc.Name: {!v.acc.Name}<br/>
    acc.Rating: {!v.acc.Rating}
</aura:application>

Client-side Controller:

({
    init : function(cmp, event, helper) {
        console.log('init');
        var action = cmp.get('c.getAcc');
        action.setCallback(this, function(response) {
            var acc = response.getReturnValue();
            acc.Rating = 'Hot';
            cmp.set('v.acc', acc);
        });
        $A.enqueueAction(action);
    }
})

Server-side controller:

public class SetFieldTestCtlr {
    @AuraEnabled
    public static Account getAcc() {
        return [SELECT Name FROM Account WHERE Id = '0015000001CQpNiAAL'];
    }
}

The result is that the 'Result' property value is not rendered:

result

What I've tried so far:

  • Using a getter & setter for the 'Rating' property (doesn't work)
  • Querying the 'Rating' field on the server-side controller (this DOES work if the Rating field is non-null)
  • Setting the 'acc' attribute's type to 'Object' (doesn't work)
  • Setting other properties on the acc object (none of these work)
5
  • query the Rating field as well
    – Ashwani
    Commented Jul 27, 2016 at 16:53
  • querying the Rating field only works if the value is non-null
    – bafuda
    Commented Jul 27, 2016 at 17:14
  • Can you try this cmp.set('v.acc.Rating', 'Hot');
    – Ashwani
    Commented Jul 27, 2016 at 17:15
  • cmp.set('v.acc.Rating', 'Hot'); Does display 'Hot'. It does not update the acc variable though so this approach will not work if you were to try to access the record in an iteration component.
    – bafuda
    Commented Jul 27, 2016 at 17:30
  • cmp.set('v.acc.Rating', 'Hot'); can be used in iteration as well. However, I have updated my answer so it can work with your approach.
    – Ashwani
    Commented Jul 27, 2016 at 18:00

2 Answers 2

4

You cannot set new properties on a record returned from the server or retrieved using cmp.get('v.[attributeName]'). The workaround is to make a copy of the object that you want to set a new property on.

<aura:attribute 
                type="Account" 
                name="acc"
 />

Your ControllerJS would be:

({
    init : function(cmp, event, helper) {
        console.log('init');
        var action = cmp.get('c.getAcc');
        action.setCallback(this, function(response) {
            // You cannot set a new property on an object returned from the server
            var acc = response.getReturnValue();

            // You can set a new property on a copy
            var accT = JSON.stringify(JSON.parse(acc));

            accT.Rating = 'Hot T';
            cmp.set('v.acc', accT);
        });
        $A.enqueueAction(action);
    }
})
6
  • This doesn't work. Once the default value is overriden with the object retrieved from the server the Rating field still cannot be set.
    – bafuda
    Commented Jul 27, 2016 at 17:12
  • @bafuda do you want to set Rating to Hot only if its null?
    – Praveen
    Commented Jul 27, 2016 at 17:26
  • @Praveen I thought that the actual use case would distract from the question. The actual use case is to set the 'sobjectType' property on records returned from the server, add them to an Object[] attribute, iterate over the Object[] attribute, and do conditional rendering based on the value of the 'sobjectType' property
    – bafuda
    Commented Jul 27, 2016 at 17:36
  • 1
    @bafuda got a workaround for you. Updated the answer.
    – Ashwani
    Commented Jul 27, 2016 at 17:55
  • @Ashwani This can be a two liner : var acc = response.getReturnValue();acc.Rating = 'Hot';cmp.set('v.acc', JSON.parse(JSON.stringify(acc)));
    – Praveen
    Commented Jul 27, 2016 at 18:13
2

Your code will work without issue, if locker service is disabled.

If the locker is in place, you could solve it by setting aura:attribute's type to Map(for now)

  <aura:attribute type="Map" name="acc"/>

But still this would be an workaround only.

9
  • Thanks Praveen. Is locker service optional? How can I disable it?
    – bafuda
    Commented Jul 27, 2016 at 17:45
  • I've tried setting the type to Map and the result is the same.
    – bafuda
    Commented Jul 27, 2016 at 17:51
  • Rating = Hot didn't reflect in the view?
    – Praveen
    Commented Jul 27, 2016 at 17:53
  • No. I'm running the same code in the post, but instead of type='Account' type='Map'
    – bafuda
    Commented Jul 27, 2016 at 17:56
  • @bafuda, i tried the same code you posted just by changing the atttribute type to Map, Rating is set to Hot, where or not it has value in it.
    – Praveen
    Commented Jul 27, 2016 at 17:56

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .