Setting up a Flow to prevent recursive menu item nesting

I have a data model (navigation_menu_items) that I have setup with parent and children to allow for nested navigation_menu_items. Currently this allows for a user to set a navigation_menu_item’s parent to itself. I’m trying to prevent this by setting up a Flow. My current flow is partially working, where it does successfully prevent a user from sending the parent to itself, but for some reason valid updates no longer will save. Like if I change the label or sent a valid parent, it will allow me to click the save button, but the data doesn’t actually change.

Here is my setup:

Trigger: Event Hook
Type: Filter (Blocking)
Scope: items.create, items.update
Collection: navigation_menu_items
Response Body: All Data

Operation: Run Scirpt
Code:
module.exports = async function (data) {
const payload = data.$trigger.payload || {};
const keys = data.$trigger.keys ||;
const currentId = Array.isArray(keys) ? keys[0] : null;
const parent = payload.parent;
// If parent equals the current ID (as string), throw an error
if (parent && currentId && String(parent) === String(currentId)) {
throw new Error(‘A menu item cannot have itself as a parent.’);
}
return data;
};

Any help would be greatly appreciated!

Great question, there is a simpler solution to solve this problem by using the field interface filter rules to just prevent selecting items during the existing query. I tested with a pages.sub_pages tree hierarchy relationship in my demo instance and the rule looks like this:

{“_and”:[{“id”:{“_neq”:“{{id}}”}},{“_or”:[{“parent_page”:{“_neq”:“{{id}}”}},{“parent_page”:{“_null”:true}}]}]}

Screen shot of the interface:

In this case the filter will exclude the current item id and also exclude any children that are already have this item as the parent. Optional for the second half, but made sense to me to include.

The variable {{id}} will pass the current item id dynamically as part of the filter query.

If you still want to use a flow, let us know and we can help you with debugging the Run Script. Quick look at this and one of the main issues is the $trigger.keys (NOTE: the shape of this can be single value or an array so that requires some validation checking to ensure you always have either an array or single value as appropriate. eg const item_id = data.$trigger.key ? data.$trigger.key : data.$trigger.keys[0]; )