" MicromOne: Preventing Duplicate Records in Power Apps: 3 Effective Strategies

Pagine

Preventing Duplicate Records in Power Apps: 3 Effective Strategies


Maintaining clean and consistent data is essential in model-driven Power Apps. One common challenge is preventing users from creating duplicate records—especially when selecting items like products, assets, or customers.

In this article, we’ll explore three practical techniques using JavaScript and the Power Apps Client API:

  • Check for duplicates before saving (with redirect)
  • Block the save using preventDefault()
  • Allow creation, then delete or deactivate with a timer

 1. Pre-Save Duplicate Check with Redirect

This method checks for duplicates when the form is in Create mode. If a duplicate is found, it alerts the user and redirects them to the existing record—without saving the current one.

Code Example: validateLookupSelection

async function validateLookupSelection(formContext) {
    const formType = formContext.ui.getFormType();

    if (formType === 1) { // 1 = Create
        const item = formContext.getAttribute("lookup_field")?.getValue();

        if (item && item.length > 0) {
            const itemId = item[0].id.replace(/[{}]/g, "");

            try {
                const query = `?$filter=_lookup_field_value eq ${itemId}&$select=recordid`;
                const results = await Xrm.WebApi.retrieveMultipleRecords("custom_entity", query);

                if (results.entities.length > 0) {
                    const existingRecordId = results.entities[0].recordid;

                    await Xrm.Navigation.openAlertDialog({
                        confirmButtonLabel: "OK",
                        text: "This item already exists.",
                        title: "Duplicate Detected"
                    });

                    // Prevent this field from being submitted
                    formContext.getAttribute("lookup_field").setSubmitMode("never");

                    // Redirect to the existing record
                    Xrm.Utility.openEntityForm("custom_entity", existingRecordId);

                    return;
                }
            } catch (error) {
                console.error("Error during validation:", error);
            }
        }

        // Optional: show a section if no duplicate is found
        formContext.ui.tabs.get("general").sections.get("general").setVisible(true);
    }
}

Learn more about setSubmitMode in the official docs.

Prevent Save with preventDefault()

If you want to completely block the save operation, use the preventDefault() method inside the form’s onsave event handler.

Code Example:

function onSave(executionContext) {
    const formContext = executionContext.getFormContext();
    const item = formContext.getAttribute("lookup_field")?.getValue();

    if (item && isDuplicate(item)) {
        Xrm.Navigation.openAlertDialog({
            title: "Duplicate Detected",
            text: "This item already exists."
        });

        executionContext.getEventArgs().preventDefault(); // Stop the save
    }
}

Learn more about preventDefault in Microsoft Docs.

 3. Timer-Based Deactivation or Deletion

Sometimes, you may want to allow the record to be created, but then automatically clean it up if it’s a duplicate. This can be done using a timer in JavaScript or with a Power Automate flow.

 JavaScript Example:

setTimeout(async () => {
    try {
        await Xrm.WebApi.deleteRecord("custom_entity", formContext.data.entity.getId());
        Xrm.Navigation.openAlertDialog({
            title: "Duplicate Removed",
            text: "This record was a duplicate and has been deleted."
        });
    } catch (error) {
        console.error("Error deleting record:", error);
    }
}, 5000); // Wait 5 seconds

Tip: Instead of deleting, you could also update a status field to mark the record as inactive.