Nested foreach loops not working as expected

I have a form within a listview that attached action items to a given session of a conference, with the option to add additional instances to the listview. Within the form is a multiselect component, to assign people to those action items. For each instance of the form, a MySQL procedure should be called that inserts the action item and returns the id of the new item, then for each selected person in that instance of the multiselect, a record should be inserted in another table using the action item id and the person id.

Instead, my query seems to be inserting all the action items first, and then afterwards, attaching all the person ids to the very last action item, regardless of which instance of the form they belong to.

This is the form:

This is my JS query:

let items = newSeshActions.instanceValues
let session_id = insert_session.data.session_id[0]
items.forEach(item => { if(item.newSeshAction != '') {insert_new_sesh_action.trigger({
additionalScope: {
action_item: item.newSeshAction,
session_id: session_id,
action_status: item.newSeshActStatus}}).then(()=> { let persons = item.newSeshActPers
persons.forEach(person => {insert_new_sesh_act_pers.trigger({additionalScope: {action_item_id: insert_new_sesh_action.data.action_item_id[0],
person_id: person}});});})}})

I've tried rearranging it in different ways and changing the way it is triggered, with no luck. I'm still fairly new to javascript so not sure how to go about introducing asynchronicity so that the queries run in the correct order.

Related, this query and several others are triggered as success handlers to another query (the insert_session query referenced above). I want to wait until all the success handler queries and all their own triggered queries and/or event handlers are finished running, and only then trigger a final success handler to clear the form. I'm sure this also involves writing an asynchronous query, but am not sure where to start. Any help is appreciated.

This has been solved with the help of Support:

let items = newSeshActions.instanceValues
let session_id = insert_session.data.session_id[0]
// Sequential loop
for (const item of items) {
if (item.newSeshAction !== '') {
// Insert parent row and wait for result
const actionRes = await insert_new_sesh_action.trigger({
additionalScope: {
action_item: item.newSeshAction,
session_id: session_id,
action_status: item.newSeshActStatus
}
})
// Pull the new action ID from the result
const action_item_id = actionRes?.[0]?.action_item_id || actionRes?.action_item_id?.[0]
// Now insert each person sequentially
for (const person of (item.newSeshActPers || )) {
await insert_new_sesh_act_pers.trigger({
additionalScope: {
action_item_id: action_item_id,
person_id: person
}
})
}
}}

1 Like

Thanks for sharing an update, @LindenKel!