Run queries in the correct order

Hi,
I'm creating an app to send emails.

I've the following flow:

  • Upload attachments using fileDropdown component
  • Click on a button to start the process
    -- On click, it runs a script triggering the query upload_attachments_i
Promise.resolve(upload_attachments_i.trigger({
  additionalScope: {
    fileDropzone_files: fileDropzone[i].files,
 fileDropzone_value: fileDropzone[i].value,
      email_body_i: richTextEditor_EmailContent[i].value.replaceAll('<p>', '<br>').replaceAll('</p>', ''),
    } 
}
));

-- upload_attachments_i calls upload_attachements_zendesk for each attachment. When attachments are finished, runs send_email to create the ticket in zendesk.

upload_attachments_i

var files = fileDropzone_files;
var data_binary = fileDropzone_value;

list_attachments.setValue([]);
function runQuery(x) {
  if (x >= files.length) {
    //console.log("Finished files");
    console.log("List attachments values", (list_attachments.value));
    console.log("Trigger send email", (list_attachments.value));
    send_email.trigger({
    additionalScope: {
      email_body: email_body_i,
      attachments: list_attachments.value
    }});
   // console.log("Reset value for attachments");
    return;
  }
  var attachment_i = files[x];
  
  var data_binary_i = data_binary[x];
  
  console.log("Run upload_attachments_zendesk");

  Promise.resolve(upload_attachements_zendesk.trigger({
    additionalScope: { filename: attachment_i.name,
                       content_type: attachment_i.type,
                       data_binary: data_binary_i
                     }, // This is where we override the `i` variable
    
    
    // You can use the argument to get the data with the onSuccess function
    onSuccess: function (data) {
      runQuery(x + 1);
    },
  }));
  
}

runQuery(0);

--- upload_attachements_zendesk is a POST API request that returns a token for each attachment and push it to list_attachments array (pushAttachments.trigger() on Success).

--- pushAttachments is a JS query to push the the tokens to list_attachments

let tempState_A = list_attachments.value,
    newData_A = upload_attachements_zendesk.rawData.upload.token,
    result_A = tempState_A.concat(newData_A);

list_attachments.setValue(result_A)
console.log("Entered in pushAttachments and this is list_attachments", (list_attachments.value));

The problem I'm struggling with is that send_email is triggered before than upload_attachements_zendesk finished and the tokens are in the list_attachments.

Here the console:

2:18:01 PM - Run upload_attachments_zendesk
2:18:01 PM - Trigger send email {}
2:18:01 PM - Success upload_attachements_zendesk
2:18:01 PM - Entered in pushAttachments and this is list_attachments {}

Running again everything it works properly, because the second time list_attachments contains the tokens.

How I can fix it?
Thanks

Anyone has some input for this?
Thanks

Hello @number15!

It seems that the issue is that the send_email query is triggered before all attachments have finished uploading and their tokens have been added to the list_attachments array.

One way to solve this would be to modify the upload_attachments_i query to wait until all attachments have finished uploading and their tokens have been added to the list_attachments array before triggering the send_email query.

You can achieve this by using Promise.all to wait for all upload_attachements_zendesk queries to resolve before triggering send_email. Here's an example code snippet (you may need to tweak the results for your specific use case):

var files = fileDropzone_files;
var data_binary = fileDropzone_value;

list_attachments.setValue([]);

var promises = [];

for (var i = 0; i < files.length; i++) {
  var attachment_i = files[i];
  var data_binary_i = data_binary[i];

  console.log("Run upload_attachments_zendesk");

  var promise = Promise.resolve(upload_attachements_zendesk.trigger({
    additionalScope: {
      filename: attachment_i.name,
      content_type: attachment_i.type,
      data_binary: data_binary_i
    },
    onSuccess: function (data) {
      var tempState_A = list_attachments.value;
      var newData_A = data.rawData.upload.token;
      var result_A = tempState_A.concat(newData_A);

      list_attachments.setValue(result_A);
      console.log("Entered in pushAttachments and this is list_attachments", (list_attachments.value));
    }
  }));

  promises.push(promise);
}

Promise.all(promises).then(function() {
  console.log("All attachments uploaded successfully");
  console.log("List attachments values", (list_attachments.value));
  console.log("Trigger send email", (list_attachments.value));

  send_email.trigger({
    additionalScope: {
      email_body: email_body_i,
      attachments: list_attachments.value
    }
  });
});

This code should trigger all the upload_attachements_zendesk queries in parallel, and then wait for all of them to resolve before triggering the send_email query.

Let me know if you have any questions at all!

Hi @victoria, thank you for your help.

It seems that list_attachments[] remains always empty now.
I assume it's not entering in the onSuccess function, since I don't see the string in the console too.

Hmm interesting :thinking: Mind if I step into your app to take a look at this? Might be easier to debug.

If so, feel free to email me link to your app!

victoria.campbell@retool-ba9e93d5caa4.intercom-mail.com

@victoria sent
Let me know when you have a chance to take a look at it.

Thanks

@victoria hi, any update on this? :innocent:
Thanks