Simple Lightning Component for Toast Alerts

It’s often useful to warn or alert users as a response to changes they make to a Salesforce record. We might have Apex trigger logic that examines the change being made, and determines that a warning is needed. What then? There is no standard facility to have the server-side Apex code surface a message to the user in the client. We can use AddError in our trigger logic, but that would rollback the user’s transaction - we don’t want that, we just want to pass a message along.

This post describes a simple and elegant way to accomplish this using a Lightning Web Component and a Platform Event. The solution is used as follows:

Setup

  1. A new Platform Event is defined - in the sample code below it is named alertToast__e. This event has attributes that include:
    1. A name field (Name__c) to label the event with the scenario that created it - e.g. “OpportunityStageChange”
    2. Fields for variant (Variant__c) and mode (Mode__c), to control the appearance and behavior of the toast alert
    3. Fields for title (Title__c) and message (Message__c), to define the toast alert contents
    4. A user field (User_Id__c) to identify the user that should receive the alert
    5. A record field (Record_Id__c) to identify the record that the alert is related to
  2. The LWC is deployed to the org

Configuring an Alert

  1. The LWC is placed on the appropriate Lightning Record Page. A component attribute “Events” is a comma-separated list of the scenarios that the component should be listening for. The component has no HTML and is invisible on the page
  2. Apex or flow logic is created to fire an alertToast__e Platform Event when needed, with the appropriate values for the event fields.

How it Works

  1. The LWC is subscribed to listen for all alertToast__e events, using the lightning/empApi module
  2. When an event is received the LWC inspects its contents to check the following conditions:
    1. Is this event for a scenario that I am configured to listen for in my Events component “Events” attribute?
    2. Is the user specified in the event the same as the current user? (or blank, meaning show the alert for all users)
    3. Is the record specified in the event the same as the current record? (or blank, meaning show the alert for all records)
  3. If all of the above conditions are true, the LWC dispatches a showToastEvent to display the alert, based on the event’s variant, mode, title, and message fields.

Sample Code

import { LightningElement, api } from "lwc";
import { subscribe, unsubscribe, onError } from "lightning/empApi";
import { ShowToastEvent } from "lightning/platformShowToastEvent";
import USER_ID from "@salesforce/user/Id";

export default class AlertToast extends LightningElement {
  @api
  events;

  @api
  recordId;

  subscription;
  channelName = "/event/alertToast__e";

  connectedCallback() {
    onError((error) => {
      console.log("Received error from server: ", JSON.stringify(error));
    });

    let that = this;
    const messageCallback = function (response) {
      if (
        that.events &&
        that.events.split(",").includes(response.data.payload.Name__c) &&
        (response.data.payload.User_Id__c === USER_ID.substring(0, 15) || response.data.payload.User_Id__c == null) &&
        (response.data.payload.Record_Id__c === that.recordId || response.data.payload.Record_Id__c == null)
      ) {
        that.dispatchEvent(
          new ShowToastEvent({
            title: response.data.payload.Title__c,
            message: response.data.payload.Message__c,
            variant: response.data.payload.Variant__c,
            mode: response.data.payload.Mode__c,
          })
        );
      }
    };

    if (subscription == null) {
      subscribe(this.channelName, -1, messageCallback).then((response) => {
        this.subscription = response;
      });
    }
  }

  disconnectedCallback() {
    unsubscribe(this.subscription);
  }
}

Final Thoughts

Note that Platform Events, on which this solution depends, are not a limitless resource. Information on Platform Event limits are described here, and careful consideration is needed before deploying a solution of this type in a large org, or for common scenarios.