TIL About Using Apex Controllers With Lightning Components

More importantly… I learned how to initialize Lightning Components from properties in an Apex Controller.

My scenario:

I wanted to display the detail page for a Contact in a lightning component.  Essentially the equivalent of “<apex:detail>” tag.  In Lightning, you can achieve this by using the “<force:recordView>” tag instead.  What I learned is that the force:recordView tag doesn’t support asynchronous updates of its data.  Meaning that when the element loads, it expects to have the “recordId” property already populated.

However, when the page first loads (without having the value passed into the component as a parameter), you need to initialize and query the data first.  So the data isn’t available on load of the element, and you get an “Invalid Page” error.

The Solution:

You need to dynamically create the <force:recordView> element from the component’s controller.js file.  Here’s some code showing how I did it:

Screen Shot 2016-02-19 at 12.55.43 AM.png
ContactDetail.cmp – used for Community Page to display a user’s Contact record

Some things to note about the component view:

  • aura:handler tag initiates a controller function, and passes in the entire state of the component, including the Apex Controller (that’s important in a moment)
  • the aura:id allows the javascript controller to find it later.  This is where we’ll populate the contact detail output.

 

Screen Shot 2016-02-19 at 12.58.37 AM.png
MyInfoController.apxc – the apex controller for the component

Some things to note about the Apex Controller:

  • We’re not populating the data in a constructor.  This is because your javascript controller will need to invoke the method asynchronously and then handle the actionResult after the data loads (aka you need to bind this controller to an apex controller method)
  • @AuraEnabled tag must be set in order for Lightning components to access the method (also applies to properties)
  • the method is static because Aura requires it (does not support class instances)

 

Screen Shot 2016-02-19 at 1.03.59 AM.png
ContactDetailController.js – the js controller for the component.

So lets take a look at what this is doing…

  1. When the component loads, the aura:handler tag calls the doInit function and passes in the component state.
  2. the “action” var is set to the Apex Controller’s “getContactId” method
  3. then we define what to do after that action completes:
    1. set the return value in an “id” var
    2. find our “contactRecord” div on the component view
    3. dynamically create a force:recordView component, and then set the body of our div to the resulting component output
  4. $A.enqueueAction kicks off the getContactId action

The end result is a few lines of code that render an entire detail page.  And you can then control your output via standard page layouts in config (just like classic salesforce).

Not all Lightning components need this type of callback/dynamic create design pattern, however there are components that do.  So be aware when designing.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s