Tag Archives: Lightning

Use showToast for taking Action After Lightning Record Edit

Whenever possible, I leverage the out-of-the-box Salesforce functionality to implement the desired functionality. One Lightning development feature I’ve used recently is the e.force:editRecord event. In a Lightning component, you can fire this event with a record id and that record’s default edit page will open in a new modal.

That’s great and saves a lot of custom coding, if that’s acceptable. However, after someone edits the record successfully, you’ll want to probably take some action such as updating the display to show the latest edits.

Problem: The force:recordSaveSuccess and force:recordSave don’t fire after the record is edited successfully, at least in Winter 18.

Solution: Use the showToast event to take action after a record is edited successfully.

In the handleToastMessage function, the code is checking for a specific “object saved message” and if it’s found, some specific actions are taken.

If you have a better way of doing this, please let us know in the comments!

Lightning Field Set Form Component

For learning purposes, I created a Lightning Field Set Form component that renders a one column form of inputs for a set of fields for a given SObject where the field inputs are driven by a specified field set on that object. This code was influenced by the How to use Field Sets with Lightning Stackoverflow post.

Use Cases

This component can be used to either update a record or create a new record.

Updating a Record

To update a record on a standard record page,

  1. Create a field set on the object that specifies the fields to edit.
  2. Place the FieldSetForm component on a record page and specify its Field Set Name on the designer tab.

To update a record from a custom component,

  1. Embed the <c:FieldSetForm /> in the custom component.
  2. Set the recordId and fieldSetName attributes with the record id and field set name to use.

Creating a Record

  1. Add the component to the desired location.
  2. In the designer, specify the object name and field set name.

Limitations

  • Needs to be enhanced to have better support for Relationship fields (Lookups & Master-Details), picklists, and multi-picklists, and probably other data types too.
  • Needs apex test code written for it.
  • Needs better error handling. It currently only shows the first error returned on save.

Notable Differences From StackOverFlow Post

  • The handleValueChange method isn’t needed to bind the input values back to the record because the cmp.getReference(‘v.record’ + field.APIName) takes care of that automatically.
  • There was a bug with the config where the same config was being used for the same type so if you had multiple fields with the same type, you’d see the same field multiple times. This was fixed by cloning the config for each field using the JSON.parse workaround.
  • Added the ability to save the record back automatically with new and update support.
  • Was able to eliminate the form attribute because all components inherit the body attribute.

Disclaimer

This was created for learning purposes. Whenever possible, use other standard components that provide similar functionality like the force:recordEdit component that does similar functionality.

Component Markup

Component Controller

Component Helper

Component Design

Apex Controller

Apex Field Class

LIGHTNING COMPONENT DEV TIPS 3

It’s been a while since I’ve posted anything on Lightning but now that I’m back in the thick of it, here are some additional tips I’ve learned from doing some more advanced, for me at least, Lightning work.

Checkout my Lightning Component Dev Tips and Lightning Component Dev Tips 2 for other tips.

Component.getReference For Dynamically Building References

getReference returns an object that can resolve itself at runtime or be able to bind to attributes. For example, you can dynamically attach event handlers to a component at run time.

Another example is dynamically binding to fields at run time.  The use case is you have a field set or other metadata that defines a list of fields to display on a lightning component. If an admin wants  to update the list of fields, they can easily do so without a developer updating the code. Unfortunately, this is not as straight forward in Lightning as it was in Visualforce. The following is NOT allowed to dynamically show a record’s fields.

getReference to the Rescue

When the list of fields are returned from an Apex callout, where the callout gets them from a field set or some other metadata, one can use the getReference function on the component to dynamically create a reference that will resolve to retrieving the field’s value from the record. Below is an example of that.

Now that the field value has been bound to the FieldValue on the Field, it’s a simple matter of iterating over it in the markup. Of course, you’d probably want to format the output further depending on the field’s type. For example, localizing a datetime or date field.

Another place where this was helpful for me was dynamically creating an input component and binding it to the component’s value field. This allowed for the two-way binding to still work for dynamically created components so that when the input value’s changed, it would also update the record’s value to easily allow the record to be upserted via an action.

Using the above helped in the creation of a FieldSetForm component that builds a dynamic set of inputs for a given SObject record driven by a field set.

Use “and” and “or” keywords in place of “&&” and “||”

The && and || operators are now allowed in the {!  } component markup for some reason. Instead, use the “and” and “or” functions that take a list of predicates and evaluate as expected.

Event Parameters Are Pass-By-Value

When passing a Javascript object through a fired event in one component as an event parameter and it’s modified on another listening component’s event handler, the object’s modified state isn’t visible on the original component that fired the event.

In other words, an event’s parameters are pass-by-value and are copied instead of pass-by-reference.

Can’t Create div, span & Other HTML elements in CreateElement or CreateElements

The ‘Type’ parameter to CreateElement and CreateElements must be an Aura or Lightning component. It can’t be a simple HTML element such as “div” or “span”. Even though they get created successfully, they don’t render on the page.

What other tips do you have? Let me know in the comments.

Coming Soon to Boostr: “View Offending PB or Flow” link in Lightning

In BOOSTR: VIEW FLOW OR PROCESS BUILDER CAUSING ERROR, the “View Offending Process Builder or Flow” link works in Salesforce Classic BUT not in Lightning Experience (LEX).

I implemented the Boostr code so now it will. A future release, coming soon, will have this functionality.

Technical Bits

This Boostr Pull Request shows how it’s implemented in Javascript.

High-level Algorithm

  1. If in Lightning Experience, add a mutation observer that reports whenever a DOM element is added or removed on the page.
  2. When the DOM changes, is the Flow Error text added?
  3. If yes, create the “View Offending Process Builder or Flow” link and append it to that error message node.

Why It Didn’t Work in Classic?

The reason is the way that Boostr for Salesforce works. When a Salesforce page is opened, it inspects which page is opened and adds the page specific features to it. For example, when the generic flow error is opened, it adds the View… link. It doesn’t look for changes to the page.

In Lightning, since it’s a Single Page Application (SPA), the page is loaded and then dynamically generated via Javascript. A new page isn’t opened when you click different links and buttons. You’re still on the same page but its contents change as different actions are performed. Since the generic flow error page is never loaded, that’s why the link never showed.

Have a feature you’d like to have in Boostr? Submit a feature request issue in GitHub and a contributor may implement it. Or you can implement it yourself by following the Contribution instructions.

Lightning Component Dev Tips 2

Here are additional dev tips that I’ve learned in the past week from being in the trenches. See Lightning Component Dev Tips for other dev tips.

Set Component Attribute Again To Rerender

I’m leveraging a complex, nested object hierarchy for my main component attribute. This object has nested nodes and each node may have additional sub-nodes. A user can interact with these nodes in various ways and so each one may get updated. One thing I discovered was that updating an attribute’s “child objects” didn’t automatically update the component’s view, even though I may have used them in the view with the {! v.Object.ChildObjects…} syntax. This is quite unfortunate because other SPA frameworks such as Angular are smart enough to attach watchers to the object properties and automatically rerender the view appropriately.

To resolve this, set the component’s attribute again in the controller code and the framework will rerender the view. I.E. component.set(‘v.attribute’, attributeValue);

Leverage Existing Components Such as Lightning Strike IO

Whenever possible, leverage existing frameworks and tools so you don’t have to reinvent the wheel. Ideally, this would be open source software so that you can contribute and enhance them too, if desired.

For example, I discovered that there’s no lookup Lightning base component, which was totally unexpected after Lightning has been out for 2 years! I didn’t want to implement this myself so I searched around and asked around about it. Craig on Slackforce pointed me to Lightning Strike, an open source project containing commonly used Lightning components that aren’t or weren’t part of the Lightning base components.

After installing the components in my dev org, I had the strike_lookup component configured and in use within 5 minutes.

Leverage Tokens

Leverage Tokens to define your CSS values and reuse them throughout your components in your codebase. This allows a more consistent UI to be more easily developed and more importantly, maintained. If you have to change your margin from 1rem to 1.5 rems, update the token in one place and everywhere it’s used inherits it automatically.

This is another application of the Single Responsibility Principle.

What dev tips do you have?

What Lightning component architecture resources do you use?