One big problem I’ve had for a long time, when running one of the above functions on an array (regular and repeater data) sometimes I need to wait until a promise is resolved before continue to the next item, use case is if the array holds IDs that you need to query, or an upload button that’s awaiting the URL of the uploaded item, it’s just insane, this where I always stuck in each project and can’t find any workarounds, the code is just ignoring the async/await as if it wasn’t there.
Any workarounds guys? Any suggestions?
Thanks in advance.
I believe the issue in such a case is that you might be hitting the limit of web/data requests (about 250 per minute). You’re right in stating that the await should actually, you know, wait until the request is finished, but the system limits are probably causing some the awaits to be “ignored” (or not resolved).
I always try to defer requests till needed, but I realize that this isn’t always possible.
I’m going to send this on to the dev team to see if they have any ideas.
Thank you Yisrael , as far as I can remember, async/await don’t work in loops with callbacks. I did find a workaround to force it to wait until all promises are resolved, but I just can’t understand why .
@ahmadnasriya Ah, I was just starting to write that you can do Promise.all(), but that doesn’t solve all cases. And yes, callbacks are a problem, but I think that I once succeeded in getting callbacks working.
@yisrael-wix yes, it wasn’t possible in my case since I was using the repeater’s forItems loop to start an upload and add the uploaded files into an array, so they need upload one at a time.
As a workaround, I created a while loop with a variable to invalidate it once the result is returned by checking if the array length is equal to the data length in the repeater before moving to the next part.
@ahmadnasriya I would like to show the devs what the problem is, so an example of the problem. Although, an example of a workaround would be great for anyone who needs this.
@yisrael-wix My scenario is a repeater where you can add/remove items from it, each item has an upload button, on submitting, a validation check is called to check if all the buttons have pending files and that they’re valid before calling another function that will start uploading file individually and add the uploaded URLs to an array to insert in a collection in a later step.
The solution is already included
let uploadedFiles = [];
let saved = false;
let finished = false;
for (let i = 0; i < $w('#rep1').data.length; i++) {
let id = $w('#rep1').data[i]._id;
await $w('#rep1').forItems([id], async ($item, itemData, index) => {
await $item('#upload').startUpload().then((uploadedFile) => {
uploadedFiles.push(uploadedFile.url);
}
}
let data = $w('#rep1').data
while (uploadedFiles.length === data.length && submitting && !saved && !finished) {
// Invalidate the loop
saved = true;
submitting = false;
// Move to the next part
}
}
@ahmadnasriya I didn’t read the entire thread, so maybe you referred to it somewhere, but why wouldn’t you do something like this in your case? :
let uploadingButtons = [];
$w("#repeater1").onItemReady ($item, itemData, index) => {
uploadingButtons.push($item("upladButton"));
})
//then when you want to start loading the files, let's say on button click:
Promise.all(uploadingButtons.map(e => e.startUpload()))
.then(r => {
let urls = r.map(e => e.url);
});
Or maybe that not what you meant (sorry I read fast)
Does saving the repeated item selector in an array lets me perform actions on that item as a repeated item from outside the repeater scoop? I haven’t thought about that before.