I have the following code. I want all four files to finish uploading before it completes the insert to the database, however even though I have used await the data insert attempts to complete while the files are still uploading and creates an error. What am I missing?
The file uploads and data insert should be triggered by the submit button click. The files upload okay just doesn't happen till after the data attempts to insert.
export function uploadwaivers() {
let files = []
for (let i = 1; i <= 4; i++) {
let x = "#uploadButton" + i;
if ($w(x).value.length > 0) { // visitor chose a file
console.log("Uploading" + i + ": " + $w(x).value[0].name + "- Please wait.")
$w("#uploadButton" + i).startUpload()
.then((res) => {
files.push(res.url);
console.log("Uploaded: " + files);
$w('#uploadButton' + i).buttonLabel = "Uploaded"
return files
})
.catch((uploadError) => {
console.log("File upload error: " + uploadError.errorCode);
console.log(uploadError.errorDescription);
});
} else { // site visitor clicked button but didn't choose a file
console.log("Waiver count: " + files.length + ". Please choose a file to upload.")
}
}
return files
}
async function datacollect() {
const waivers = await uploadwaivers();
let toInsert = {
"name": $w('#firstNameTxt').value,
"lastName": $w('#lastNameTxt').value,
"email": $w('#emailTxt').value,
"address": $w('#addressentry').value,
"phone": $w('#phoneNumber').value,
"street": $w('#street').value,
"unit": $w('#unit').value,
"city": $w('#city').value,
"province": $w('#subdivision').value,
"postcode": $w('#postcode').value,
"country": $w('#country').value,
"membershipType": $w('#membershipOption').value,
"language": language,
"gender": $w('#gender').value,
"waiver1": waivers[0],
"waiver2": waivers[1],
"waiver3": waivers[2],
"waiver4": waivers[3],
"dateOfBirth": $w('#dob').value,
"ltsDescription": $w('#ltsText').value,
"discount": $w('#discount').value,
"bursary": $w('#bursary').value,
"volunteer": $w('#helpTags').value,
"photos": $w('#photoCheckbox').value
}
return wixData.insert("Registration", toInsert)
}
export function btnSubmit_click(event) {
if ($w('#firstNameTxt').valid && $w('#lastNameTxt').valid && $w('#emailTxt').valid && $w('#phoneNumber').valid && $w('#membershipOption').valid && $w('#city').valid) {
datacollect().then((res) => {
let item = res;
console.log("uploaded to database", res._id);
})
.catch((err) => {
let errorMsg = err;
console.log("your upload failed");
});
}
}
So I thought it might have been due to the return files inside the for loop but that didn't make a difference. Would appreciate if anyone has any ideas.
Thanks for the feedback. I attempted a few changes but I think there is something up with using the startupload() function. The logs seem to suggest that it is not waiting till each of the startupload() loops complete until moving on to the next.
This is the log I am getting from the code below. The backend code shouldn't run until the uploads are complete as they are called in the afterinsert hook
export async function uploadwaivers() { let files = [] for (let i = 1; i <= 4; i++) { let x = "#uploadButton" + i; if ($w(x).value.length > 0) { // visitor chose a file console.log("Uploading" + i + ": " + $w(x).value[0].name + "- Please wait.") $w("#uploadButton" + i).startUpload() .then((res) => { files.push(res.url); console.log("Uploaded: " + files); $w('#uploadButton' + i).buttonLabel = "Uploaded" return files }) .catch((uploadError) => { console.log("File upload error: " + uploadError.errorCode); console.log(uploadError.errorDescription); }); } else { // site visitor clicked button but didn't choose a file console.log("Waiver count: " + files.length + ". Please choose a file to upload.") } } return files } async function datacollect() { const waivers = await uploadwaivers(); let toInsert = { "name": $w('#firstNameTxt').value, "lastName": $w('#lastNameTxt').value, "email": $w('#emailTxt').value, "address": $w('#addressentry').value, "phone": $w('#phoneNumber').value, "street": $w('#street').value, "unit": $w('#unit').value, "city": $w('#city').value, "province": $w('#subdivision').value, "postcode": $w('#postcode').value, "country": $w('#country').value, "membershipType": $w('#membershipOption').value, "language": language, "gender": $w('#gender').value, "waiver1": waivers[0], "waiver2": waivers[1], "waiver3": waivers[2], "waiver4": waivers[3], "dateOfBirth": $w('#dob').value, "ltsDescription": $w('#ltsText').value, "discount": $w('#discount').value, "bursary": $w('#bursary').value, "volunteer": $w('#helpTags').value, "photos": $w('#photoCheckbox').value } //return wixData.insert("Registration", toInsert) return toInsert } export function btnSubmit_click(event) { if ($w('#firstNameTxt').valid && $w('#lastNameTxt').valid && $w('#emailTxt').valid && $w('#phoneNumber').valid && $w('#membershipOption').valid && $w('#city').valid) { datacollect().then((toInsert) => { wixData.insert("Registration", toInsert).then((res) => { let item = res; console.log("uploaded to database", res._id); }) .catch((err) => { let errorMsg = err; console.log("your upload failed"); }); }); } }
Another way of doing it might be to call the uploadwaivers() function from the button_click event, (without the await keyword), and then call your datacollect() function from inside the .then section of the uploadwaivers function.??
JS async operations do my head in too! However, one thing I can see, is that you are calling the function uploadwaivers() with the await key word, but you have not defined that function as an async function, therefore the code following the line "const waivers = await uploadwaivers();" will simply execute immediately without waiting for this function to complete.