I have a little script setup here. After the script runs, when I return the value of the variable 'changed'. nothing is returned. I can't seems to get to the bottom of why this is. As far as I can see, I have accounted for the asynchronized nature of the script and it seems to me that I am awaiting things in the correct places and returning data back up through the pattern correctly. Any insights will be appreciated.
async function processItem(item) {
await Promise.all([
item.drawings = translateDrawingControl.trigger({additionalScope : {"queryItems" : item.drawings}}),
item.images = uploadFiles.trigger({additionalScope : {
"queryItems" : item.images,
"folderId" : "17LtxvNx3TVR_G7HRg8CHYmd7CSAGl1L5",
}}),
item.files = uploadFiles.trigger({additionalScope : {
"queryItems" : item.files,
"folderId" : "1NjfHx67vguloeLizitwSQs41-jPpf7Sm",
}}),
]);
return item;
}
let changed = itemChanged.value;
beingProcessed.setIn([changed[0].part_number], true);
changed = await Promise.all(changed.map(mapData => {
beingProcessed.setIn([mapData.id], true);
return processItem(mapData);
}));
return changed;
I just solved this by changing the function to this.
async function processItem(item) {
let processedData = await Promise.all([
translateDrawingControl.trigger({additionalScope : {"queryItems" : []}}),//item.drawings}}),
uploadFiles.trigger({additionalScope : {
"queryItems" : item.images,
"folderId" : "17LtxvNx3TVR_G7HRg8CHYmd7CSAGl1L5",
}}),
uploadFiles.trigger({additionalScope : {
"queryItems" : item.files,
"folderId" : "1NjfHx67vguloeLizitwSQs41-jPpf7Sm",
}}),
]);
item.drawings = processedData[0];
item.images = processedData[1];
item.files = processedData[2];
return item;
}
I am still not sure why assigning the returned query data directly from within the Promise.all would have caused nothing to be returned by the async function.
Hey @Shawn_Crocker! Glad you were able to get this resolved.
It looks like in your original query item.drawings
was receiving the promise itself, not the result of the promise. JS query return values are limited by the postMessage API and will fail to pass a promise to the model. Note that you won't see this if you return the promise directly (e.g. return yourQuery.trigger()
) because Retool will recognize it and instead let the query run until the promise resolves and then return the value. That won't happen if the promise is nested in an object though:

You can typically get around this by using await
wisely in your query, as you did! 
Hopefully that helps to shed some light on the situation.
Ok. So in the original, it was like the assigned tasks for the Promise.all was to simply assign a promise to an object but its job was not to actually process the promise. Like the promise was not in the correct scope to actually get caught and handled by the Promise.all.
Kind of? It looks to me like your await
s were set up correctly so that all the promises would finish, they just don't get unwrapped.
If you assign a promise to a variable, even if you wait for that promise to finish, that variable still holds the promise object instead of the result object:

That's different from using await
directly in the assignment:

If you were to try console logging changed
in your original script, I suspect you would see a bunch of completed promises that are causing errors when you try and return them:

At the risk of confusing things further, Retool can recognize this and get around it if you return the promise directly:

But if there's any kind of nesting it doesn't work:

2 Likes