Executing Queries with different names

Here is an image of my current code.
retoolhelp

So in short I will have a lot of different queries that essentially do the same thing but with different authorizations for different results.

I have named the queries as you've seen TENANTNAMEGraphReportQuery and I would like to be able to execute them by putting the tenant name in the function call. I was just asking if its possible at all to do this. and If anyone has a solution other than using eval (I know its not great but the string that's inputted is pre-defined option so I figured it was ok)

Thank you in advance! :smile:

Hey @SycloneCarson!

You might be able to get minimal usage of eval if you run it on just the query name itself, e.g. something like:

const tenantQuery = eval(tenantName + 'GraphReportQuery');
tenantQuery.trigger({/* ... etc.*/});

Aside from that, is there a particular reason you're using dynamically defined queries? Maybe there's something available that can help there!

1 Like

I would love to have a single query but I cannot pass a variable from the application to the Resource Authentication. If you know a way of doing that, itd be great! The endpoint I authorize determines what data I access with the same query so having to have multiple queries just to change a single part of the auth URL is annoying

I see, that is tricky to work around. One option might be this beta feature that lets you dynamically specify which resource a query uses. If that looks preferable let me know and I can turn it on for you :slightly_smiling_face:

That certainly may help! I appreciate your assistance.

I have tried that code you sent and it only seems to be working ~half the time. It wouldn't work at first but now it seems to be working for at least one tenant.

It gives me the error

Error: sycloneGraphReportQuery is not defined

I have even copy pasted the name over so I'm not sure why its saying its undefined haha

const pullData = function (tenantName) {
    const tenantQuery = eval(tenantName + 'GraphReportQuery');
    new Promise((resolve) => {
        tenantQuery.trigger({
            onSuccess: (data) => {
                console.log(`Pulled data from ${tenantName}`)
                resolve(data);
            }
        });
    });
}

for (const element of tenantSelecter.value) {
    console.log(`Pulling data from ${element}`);
    await pullData(element)
}

I apologize if this is something dead simple Im just missing but I cannot see whats wrong.

That is odd! Not sure what's going on :thinking:

I turned the feature on for you. It might be better to explore that route before diving too deep into getting eval working :sweat_smile:

I have realized that I have a secondary query that merges data for me. It would also be far more modular to use this eval function there. I'm getting the same error while not using promises so I'm unsure what's going on.

I am looking into a solution for swapping the main queries out for this new feature but I don't believe I can use it with the merge JS query.

Are their any logs or details I can supply to help you? Once more, Thank you @Kabirdas :slightly_smiling_face:

It might be helpful to more about your merge query! What does the code for that look like?

Hey @Kabirdas I apologize for the delay.

Here is the code for the mergerJSON:

mergerJSON.reset();
let mergedResponses = [];

const combineArray = function (dataToMerge) {
  if (dataToMerge !== null) {
    mergedResponses = mergedResponses.concat(dataToMerge)
  } else {
    console.log("Dataset to be merged is empty.")
  }
}

for (const element of tenantSelecter.value) {
  console.log(`Merging ${element}'s data.'`);
  const tenantQuery = eval(element + 'GraphReportQuery');

  combineArray(tenantQuery.data);

}

return mergedResponses;

It is called at the end after everything has been pulled from the API.

Hey @SycloneCarson, no worries!

Would it work to keep a record of each tenant query at the top of your merger script? Something like:

const tenantQueries = {
fooGraphReportQuery,
barGraphReportQuery,
/* etc. */
};

And then reference them with

const tenantQuery = tenantQueries[element + 'GraphReportQuery'];

I know that adds an extra layer of maintenance, but even when using eval I believe Retool objects will need to be declared at the start of your script.

And it works!! Thank you so much @Kabirdas.

Just some quick afterthought questions:

Can I set tenantQueries dynamically by pulling from the list of tenants I already have or do I need to set them the same way.

Also do you know a way of waiting for all of the queries to be finished before starting the merger query? I had promises working but now they aren't as I believe the function/for loop messes them up.

Thank you!

I think they need to be hardcoded, but hopefully, it's easier to maintain that list.

For your second question, I'm afraid I got a bit lost with the switch to the merge query :sweat_smile: It looks like you can call the queries and merge their result together in the same script with a pattern like this. You definitely don't have to rewrite all your code though, I think Promise.all might be useful to look into either way.

If you don't mind sharing your current iteration once more I can take a look at that as well :slightly_smiling_face: