I have a LWC with a datatable with a Row Action button. When the Action button is clicked, I open a modal window where I want to collect some information. How do I wait for the modal to close before continuing with the rest of my processing. I would also like to know if the modal was closed with a Save or a Cancel.


    <!-- Lightning Datatable for App Definition record selection -->

    <!-- Popup modal to request image file name     -->
    <template if:true={requestImageNameModal}>
        <div style="height:200px; width:500px;">
            <section role="dialog" tabindex="-1" aria-labelledby="modal-heading-01" aria-modal="true" aria-describedby="modal-content-id-1" class="slds-modal slds-fade-in-open">
                <div class="slds-modal__container">
                    <header class="slds-modal__header">
                        <button class="slds-button slds-button_icon slds-modal__close slds-button_icon-inverse" title="Close" onclick={handleCancelModal}>
                            <lightning-icon icon-name="utility:close" size="medium">
                            <span class="slds-assistive-text">Close</span>
                        <h2 id="modal-heading-01" class="slds-text-heading_medium slds-hyphenate">{displayAppLabel}</h2>
                    <div class="slds-modal__content slds-p-around_medium" id="modal-content-id-1">
Add Lightning-Input Here
                    <footer class="slds-modal__footer">
                        <lightning-button label="Cancel" variant="neutral" onclick={handleCancelModal} class="slds-m-right_medium"></lightning-button>
                        <lightning-button label="Save" variant="brand" onclick={handleSaveModal}></lightning-button>
            <div class="slds-backdrop slds-backdrop_open"></div>            


import { LightningElement, api, track } from 'lwc';

    // datatable columns Label, LogoUrl, NavType | UiType, DeveloperName, NamespacePrefix
    const COLUMNS = [
            label: 'App Name',
            fieldName: 'Label',
            type: 'text',
            sortable: 'true',
            initialWidth: 280
            label: 'Nav Type',
            fieldName: 'NavType',
            type: 'text',
            sortable: 'true',
            initialWidth: 100
            label: 'Image Link',
            fieldName: 'LogoUrl',
            type: 'url',
            typeAttributes: { target: '_blank'},
            sortable: 'true',
            initialWidth: 550
            label: 'Select Apps',
            type: 'button',
            typeAttributes: { 
                label: 'Select',
                name: 'select',
                title: 'Click to Add this App to your Quick Switcher list',
                disabled: { fieldName: 'buttonDisabled' }
            initialWidth: 90

    const MYDATA = [
            DeveloperName: '',
            Label: '',
            NavType: '',
            LogoUrl: '',
            buttonLabel: '',
            buttonDisabled: ''

export default class QuickAppSwitcherDt extends LightningElement {

    @api tableData;
    @api selectedData;
    @api AppAPINames;
    @api AppImageNames;
    @api AppAlternateTexts;
    @api displayAppLabel;
    @api modalExitMode;
    @api columns = COLUMNS;
    @api keyfield = 'DeveloperName';
    @api sortedBy;
    @api sortedDirection;
    @api maxRowSelection;
    @api hideCheckboxColumn;
    @track preSelectedIds = [];
    @track mydata = MYDATA;
    @track requestImageNameModal = false;

    connectedCallback() {
        // Add fields to datatable records
        this.mydata = this.tableData.map(tableRecord => ({
            DeveloperName: tableRecord.DeveloperName,
            Label: tableRecord.Label,
            NavType: tableRecord.NavType,
            LogoUrl: tableRecord.LogoUrl,
            buttonDisabled: false        
        this.hideCheckboxColumn = true;

    handleRowAction(event) {
        // Disable the button and process the record here
        const action = event.detail.action;
        const row = JSON.parse(JSON.stringify(event.detail.row));
        const keyValue = row[this.keyfield];
        this.mydata = this.mydata.map(rowData => {
            if (rowData[this.keyfield] === keyValue) {
                switch (action.name) {
                    case 'select':
                        // Call function to process the selected row
                        if (this.processRowSelection(rowData)) {    // ***** This is where I want to wait and determine if the modal was closed with Save or Cancel *****

                            // Disable the button from being selected again
                            rowData.buttonDisabled = true;

                            // If not already selected, highlight the row as selected
                            if(this.preSelectedIds.indexOf(rowData[this.keyfield]) === -1) {
                                this.preSelectedIds = [...this.preSelectedIds];

            return rowData;

    processRowSelection(rowData) {
        // Add to the QuickSwitchApp metadata parameters
        this.displayAppLabel = rowData.Label;
        this.requestImageNameModal = true;
        return this.modalExitMode;

    handleCancelModal() {
        this.requestImageNameModal = false;
        this.modalExitMode = false;

    handleSaveModal() {
        this.requestImageNameModal = false;
        this.modalExitMode = true;

    handleSave(event) {
        // Only used with inline editing

    cancelChanges(event) {
        // Only used with inline editing

    getSelectedName(event) {
        // Only used with row selection

    updateColumnSorting(event) {
        // Handle column sorting
        this.sortedBy = event.detail.fieldName;
        this.sortedDirection = event.detail.sortDirection;
        let fieldValue = row => row[this.sortedBy] || '';
        let reverse = this.sortedDirection === 'asc'? 1: -1;
        this.mydata = [...this.mydata.sort(


As far as I understand your question. Per the above code, you have 2 function:

handleCancelModal() {
        this.requestImageNameModal = false;
        this.modalExitMode = false;

    handleSaveModal() {
        this.requestImageNameModal = false;
        this.modalExitMode = true;

These functions are bound to the modal window cancel and save button's click actions respectively. So you can create your variable that stores if cancel or save was used to close the modal.

Now for how to wait for the modal to close before continuing processing. Ideally it should not matter as the the actions will be performed with in the same render cycle.

If you want to do some actions to be executed after the current render cycle, you can always use setTimeout. You can execute the code to hide the modal window before the setTimeout.

handleSaveModal() {
    this.requestImageNameModal = false;
    this.modalExitMode = true;
    setTimeout(() => {
|improve this answer|||||

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.