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 Jul 27 '16 at 16:53
  • querying the Rating field only works if the value is non-null – bafuda Jul 27 '16 at 17:14
  • Can you try this cmp.set('v.acc.Rating', 'Hot'); – Ashwani Jul 27 '16 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 Jul 27 '16 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 Jul 27 '16 at 18:00
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 Jul 27 '16 at 17:12
  • @bafuda do you want to set Rating to Hot only if its null? – Praveen Jul 27 '16 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 Jul 27 '16 at 17:36
  • 1
    @bafuda got a workaround for you. Updated the answer. – Ashwani Jul 27 '16 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 Jul 27 '16 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 Jul 27 '16 at 17:45
  • I've tried setting the type to Map and the result is the same. – bafuda Jul 27 '16 at 17:51
  • Rating = Hot didn't reflect in the view? – Praveen Jul 27 '16 at 17:53
  • No. I'm running the same code in the post, but instead of type='Account' type='Map' – bafuda Jul 27 '16 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 Jul 27 '16 at 17:56

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.