3

This is the code that I am trying to execute as below(code from Lightning Documentation with some addon)

Component:

<aura:component
    implements="flexipage:availableForRecordHome,force:lightningQuickActionWithoutHeader,force:hasRecordId">

<aura:attribute name="record" type="Object"/>
<aura:attribute name="recordError" type="String"/>
<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>

<force:recordPreview aura:id="recordLoader"
  recordId="{!v.recordId}"
  layoutType="FULL"
  targetRecord="{!v.record}"
  targetError="{!v.recordError}"
  />

<!-- Display a header with details about the record -->
<div class="slds-page-header" role="banner">
    <p class="slds-text-heading--label">{!v.record.Name}</p>
    <h1 class="slds-page-header__title slds-m-right--small
        slds-truncate slds-align-left">{!v.record.BillingCity}, {!v.record.BillingState}</h1>
</div>

<!-- Display Lightning Data Service errors, if any -->
<aura:if isTrue="{!not(empty(v.recordError))}">
    <div class="recordError">
        <ui:message title="Error" severity="error" closable="true">
            {!v.recordError}
        </ui:message>
    </div>
</aura:if>

Controller.js

({
    doInit: function(cmp) {
      var act = component.get("v.record");
      console.log("act "+ act);  //returns "act null"
    }
})

But, it returns "act null"

I able to get the account records when using aura:doneRendering, could it be the only way of getting the record?

2 Answers 2

2

Record loading happens after component initialized(see the output screenshot). But you can use recordUpdated event of force:recordPreview,instead of the unreliable event aura:doneRendering(Because this is fired more than once unless your component is in isolation).

recordUpdated event is firing only once when I added the below component on the Account layout.

As per the docs,

The event fired when the record is loaded, changed, updated, or removed.

Here is the sample code:

HelloWorld.cmp:

<aura:component
    implements="flexipage:availableForRecordHome,force:lightningQuickActionWithoutHeader,force:hasRecordId">

  <aura:attribute name="record" type="Object"/>
  <aura:attribute name="recordError" type="String"/>
  <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>

  <force:recordPreview aura:id="recordLoader"
    recordId="{!v.recordId}"
    layoutType="FULL"
    targetRecord="{!v.record}"
    targetError="{!v.recordError}"
    recordUpdated="{!c.recUpdatedEvent}"
    />
</aura:component>

HelloWorldController.js:

({
    doInit: function(cmp,event,helper) {
      var act = cmp.get("v.record");
      console.log(act);  //returns null
    },
    recUpdatedEvent: function(cmp,event,helper) {
      var act = cmp.get("v.record");
      console.log(act);  //returns Account object
    }   
})

Output:

enter image description here

Note: My dev edition org is on Spring'17.

EDIT: Updated to show that record is loaded after init event.

1
  • Ah, Yes! That works. I was worried about using aura:doneRendering and missed this. Thanks :) Feb 10, 2017 at 7:40
0

All operations with records via force:recordPreview are asynchronous. This is because they may require a server trip (eg cache miss during a load).

force:recordPreview fires a force:recordUpdated event when the record state changes: error, load, update, delete. If you need logic to run beyond rendering or what's driven by the cmp then you can listen to this event.

https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/data_service_handling_record_change.htm provides a good example (with code) of this.

Component:

<force:recordPreview aura:id="forceRecord"
  recordId="{!v.recordId}" 
  layoutType="FULL"
  targetRecord="{!v._record}"
  targetError="{!v._error}"
  recordUpdated="{!c.recordUpdated}" />

Controller:

({
  recordUpdated: function(component, event, helper) {

    var changeType = event.getParams().changeType;

    if (changeType === "ERROR") { /* handle error; do this first! */ }
    else if (changeType === "LOADED") { /* handle record load */ }
    else if (changeType === "REMOVED") { /* handle record removal */ }
    else if (changeType === "CHANGED") { /* handle record change */ }
})

In other words, move your logic from your controller's init handler to a force:recordUpdated handler. In this case it'd be in the changeType === "LOADED" if block.

For completeness, see these links for when the init and aura:doneRendering events are fired:

You must log in to answer this question.

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