Here is my situation: I have a form where dancers can sign up to be part of pieces, and upon submission they get an email telling them if they joined or if they ended up on a waitlist. To do this, I first insert the current user into a piece using insertReference, then query the piece using queryReferenced to determine their spot in the waitlist. Here is my code:
async function submitJoin(piece, user) { try { await wixData.insertReference(“Pieces”, “signups-4”, piece[‘_id’], user[‘_id’]); let res = await wixData.queryReferenced(“Pieces”, piece[‘_id’], “signups-4”, {“options”: “asc”}); let dancers = res.result.items; let index = dancers.findIndex(dancer => dancer[‘_id’] === user[‘_id’]); if (index >= piece[‘cap’]) { return [piece[‘piece’], (index - piece[‘cap’] + 1)];
} else if (index >= 0) { return [piece[‘piece’], 0];
} else { // User not present in piece throw new Error(“Dancer unsuccessfully joined”);
}
} catch (err) { throw err;
}
}
What is frustrating however is that sometimes (not always!) I would get a “Dancer unsuccessfully joined” error, even though in reality the dancer does get added to the piece in the database. I’m assuming that this occurs because the queryReferenced function gets called before the insertReference function finishes executing. But clearly I’m using two awaits in a row, forcing the functions to execute sequentially, so this shouldn’t happen?
@connectine No, await behaves differently from .then(), which is exclusive to promises in JS. It’s worth reading up on on the MDN webdocs if you’re curious as to why, but you can have await statements inside your then() as well.
@connectine Again, queryReferenced is another promise, so you have to create an additional then statement, and that’s where your data will be reachable.
promiseName().then(dataReturned => {
const datafromPromiseName = dataReturned;
console.log(typeof dataReturned); /*returns 'object'
the object returned contains the items key where the info you want is stored
*/
});
@connectine Read up on the docs I mentioned before and console.log() your data. It will help you understand the data structure. res.result.items I guarantee does not exist.
@skmedia If res.result.items does not exist, then why is it possible for the code to execute perfectly on some occasions, but not others?
Plus, reading the MDN docs on Promises and async/await has only made me more confused, since it seems like my code is running contrary to the specifications. The MDN docs specifically say:
*The * awaitexpression causesasyncfunction execution to pause until aPromiseis settled (that is, fulfilled or rejected), and to resume execution of theasyncfunction after fulfillment. When resumed, the value of theawait * expression is that of the fulfilled * Promise.
So clearly having the following code:
await wixData.insertReference("Pieces", "signups-4", piece['_id'], user['_id']);
let res = await wixData.queryReferenced("Pieces", piece['_id'], "signups-4", {"options": "asc"});
would ensure that the submit function pauses until insertReference’s promise has been resolved, then executes queryReferenced and pauses until queryReferenced’s promise has been resolved.
EDIT: I did a console.log on dancers, and it does indeed exist.
So I have moved this code from the backend to the frontend, and it seems to have worked? I tried submitting several times and I have not seen a single “Dancer unsuccessfully joined” error yet. So this might be a bug on Corvid’s part that’s specific to backend code.
Sorry, I was thinking of a different wixData API. The reference API’s have their own data structure apart from the others. If you were having trouble getting it from the backend, it probably had to do with the return statement itself being unreachable. Also you have to export the function in order to later import it to your page code (if that’s what you were trying to do). With nested promises, you have to return each and every nested promise.
export function foo() {
return promise1().then(r => {
return promise2().then(res => {
return res === r;
});
});
}