Intermediate 15 min read

Toasts, Spinners, and Modals

By the end of this lesson, you'll be able to:

  • Recall when to use toasts and spinners from Module 8
  • Build and open a modal dialog using the LightningModal base module
  • Pass data into a modal and receive a result back on close

Prerequisites: "Record, Object, and List View Navigation"

Recap: Toasts and Spinners

Module 8 covered ShowToastEvent for brief notifications and lightning-spinner for in-progress loading feedback. Both remain exactly as useful here — this lesson adds the third major UX surface: modals.

Building a Modal with LightningModal

// confirmDialog.js
import LightningModal from 'lightning/modal';
import { api } from 'lwc';

export default class ConfirmDialog extends LightningModal {
    @api message;

    handleCancel() {
        this.close('cancel');
    }

    handleConfirm() {
        this.close('confirm');
    }
}
<!-- confirmDialog.html -->
<template>
    <lightning-modal-header label="Please Confirm"></lightning-modal-header>
    <lightning-modal-body>
        <p>{message}</p>
    </lightning-modal-body>
    <lightning-modal-footer>
        <lightning-button label="Cancel" onclick={handleCancel}></lightning-button>
        <lightning-button variant="brand" label="Confirm" onclick={handleConfirm}></lightning-button>
    </lightning-modal-footer>
</template>

A modal is its own component, extending LightningModal instead of LightningElement — it comes with lightning-modal-header/-body/-footer structural components, and this.close(result) is how it closes itself and passes a result back.

Opening the Modal and Reading Its Result

import ConfirmDialog from 'c/confirmDialog';

async handleDelete() {
    const result = await ConfirmDialog.open({
        size: 'small',
        message: 'Are you sure you want to delete this record?',
    });

    if (result === 'confirm') {
        // proceed with the delete
    }
}

.open() is Promise-based (Module 4's async/await applies directly) — it resolves with whatever value was passed to this.close(...) inside the modal. Any property passed into .open() besides size becomes an @api property on the modal component, exactly like a parent passing a property to a child (Module 5).

Exercise

Write the handleCancel and handleConfirm methods for a modal that closes with the string "cancelled" or "confirmed" respectively.

Show hint

Use this.close(result).

JAVASCRIPT

Exercise

Challenge: explain, as a comment, why ConfirmDialog.open(...) can be awaited just like an LDS or Apex call from earlier modules.

Show hint

Recall what .open() returns.

JAVASCRIPT

Toasts, Spinners, and Modals Quiz

1. What base class does a modal component extend instead of LightningElement?

2. How does a modal close itself and return a result?

3. What does calling .open() on a modal component return?

4. How does a property passed into .open({...}) become available inside the modal component?

5. What structural components does LightningModal provide for laying out a modal?

Log in to submit the quiz and save your score.

My Notes

Log in to keep private notes on this lesson.

Questions about this lesson

No questions yet — be the first to ask.

Log in to ask a question about this lesson.

Summary

Toasts, spinners, and modals are the three core feedback and interaction surfaces beyond the main page — modals in particular need their own dedicated component and a Promise-based open/close pattern.