javascriptasync-awaitwatermelondb

Multiple Async Await with for loop


I want to run multiple functions with async/await including a for loop as well. The loop also needed to be run one another is done. Currently I'm using this function and seems like it is not working correctly.

For the for loop query I need the id created in first query to perform it.

const createStudent = async (studentObj) => {
    try {
        await database.action(async () => {
            const newStudent = await studentCollection.create(student => {
                student.name = studentObj.name
                student.age = studentObj.age
            })

            for (let contactObj of studentObj.contacts) {
                try {
                    await contactCollections.create(contact => {
                        contact.student_id = newStudent.id
                        contact.type = contactObj.type
                        contact.contact = contactObj.contact
                    })
                } catch (error) {
                    console.log(error);
                }
            }
        })
    } catch (error) {
        console.log(error);
    }
}

currently I'm getting an error

[WatermelonDB] The action you're trying to perform (unnamed) can't be performed yet, because there are 2 actions in the queue. 
Current action: unnamed. Ignore this message if everything is working fine. 
But if your actions are not running, it's because the current action is stuck. 
Remember that if you're calling an action from an action, you must use subAction(). See docs for more details.

Solution

  • Yes you are right!. It will not work properly with multiple database create record requests together.

    Whenever you make more than one change (create, delete or update records) in an action, you should batch them.

    See: https://nozbe.github.io/WatermelonDB/Actions.html

    You can do like that:

    const batchActions = [];
    
    for (let contactObj of studentObj.contacts) {
      batchActions.push(
        contactCollections.prepareCreate(contact => {
          contact.student_id = newStudent.id
          contact.type = contactObj.type
          contact.contact = contactObj.contact
        })
      )
    }
    
    database.batch(batchActions)

    Hope this will solve your problem