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

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.

  • Ah, Yes! That works. I was worried about using aura:doneRendering and missed this. Thanks :) – Raghavendhra Yarlagadda Feb 10 '17 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:

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.