[SalesForce] component.set not setting attribute value from data.getReturnValue in action.setCallback

I am using this component: https://developer.salesforce.com/docs/component-library/bundle/lightning:map/ and instead of having a hard coded I am trying to grab the billing and shipping addresses from an Account, setting the value in an attribute and then getting the attribute when setting the map markers.

Issue: I am not able to set the attribute in action.setCallback to the value that is being returned by the Apex method.

The console.log (line 10 and 13) in my helper print {Object Object}. The system.debug in my Apex class is returning the right Account so I knows its not issue with my server-side controller.

component:

<aura:component controller="MapApexController" implements="flexipage:availableForAllPageTypes,force:hasRecordId" access="global">

<!-- attributes -->
<aura:attribute name="mapMarkers" type="Object"/>
<aura:attribute name="zoomLevel" type="Integer" />

<aura:attribute name="recordId" type="Id"/>

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

<!-- handlers-->
<aura:handler name="init" value="{! this }" action="{! c.init }"/>

<!-- the map component -->
<lightning:map 
    mapMarkers="{! v.mapMarkers }" 
    zoomLevel="{!v.zoomLevel}" />

</aura:component>  

controller:

({
    init: function (cmp, event, helper) {

        helper.getAccount(cmp);

        console.log('account: ' + cmp.get('v.myAccount'));

        cmp.set('v.mapMarkers', [
            {
                location: {
                    Street: cmp.get('v.myAccount.BillingStreet'),
                    City: cmp.get('v.myAccountBillingCity'),
                    State: cmp.get('v.myAccount.BillingState')
                },

                title: cmp.get('v.myAccount.Name') + ' \'s Billing Address',
            }, 
        ]);
        cmp.set('v.zoomLevel', 16);
    }

});

helper:

({
    getAccount : function(cmp, event, helper) {

        var action = cmp.get('c.getAccount');

        action.setParams({
            recordId: cmp.get('v.recordId')});

        action.setCallback(this, function(data){
            console.log('data line 10: ' + data.getReturnValue());
            var state = data.getState();
            if (state === 'SUCCESS') {
                console.log('data line 13: ' + data.getReturnValue());
                cmp.set('v.myAccount', data.getReturnValue());
            }
        });

        console.log('BillingCity: ' + cmp.get('v.myAccount'));

        $A.enqueueAction(action);
    }
})

Apex:

public class MapApexController{

    @AuraEnabled
    public static Account getAccount(Id recordId){

        Account acc = [SELECT Name, BillingStreet, BillingState, BillingCity, 
                            ShippingStreet, ShippingState, ShippingCity
                        FROM Account
                        WHERE Id =: recordId];

        system.debug(acc);
        return acc; 
    }
}

Best Answer

helper.getAccount is asynchronous. This means that until your init method has finished, myAccount will definitely be a null value, as you haven't had a chance to visit the server yet. You'll need to set mapMarkers after you've had a chance to load the data from the server. You'll want to read about how to Write Asynchronous JavaScript for more information on how you can simplify your code.

Related Topic