Loading is disappearing and come back

thank you so much for those solutions

can I know why inside query2.trigger are we triggering other queries ? can we make for example also for query3 onSuccess to trigger query4?

for example query2, depends on query1, query3 depends on query2 which method would you suggest

I'm having an issue because queries are called in unordered way

query1.trigger({                              //start query1
  onSuccess: function(data) {         //query1 finished successfully                                                       
    query2.trigger({                          //start query2
      onSuccess: function(data){      //query2 finished successfully
        query3.trigger({                      //start query3
          onSuccess: function(data){  //query3 finished successfully
           
          }
        }
      }
    }
  }
}));

Should I put inside async function or leave like this as you sent me

if await is not used, you do not need async. shouldvl be good to go

2 Likes

what do you think is this good approach to go with

async function processClients() {
loading.setValue(true)
try {
await fetchClients.trigger();
await extractRealClients.trigger();
await calculateStatistics.trigger();
await fetchClientsPrevYear.trigger();
await extractRealClientsPrevYear.trigger();
await calculateStatisticsPrevYear.trigger();
await calculatePercentages.trigger();
await fetchClientDetails1Year.trigger();
await extractThreeLastMonths.trigger();
await statisticsThreePrevMonths.trigger();
console.log("All operations completed successfully.");
} catch (error) {
console.error("An error occurred during the process:", error);
} finally {
loading.setValue(false)
}
}

// Make sure to call the function to execute the async process.
processClients();

that should fix your loading flicker/disappearing problem. let me know if its not working as expected

yes it working properly just a bit worried if any of queries fails will this code perform okay

no it probably won't be ok. if one of those queries fails the queries after it will still run. you'll need to there was a bug at one point that kept this code from working, there's been no update on the post tho. you could do the promise.all() if you want to stop running queries if one of them fails or you can wrap them all up in a promise w resolve/reject tokens passed to onSuccess/onFailure.

async function processClients() {
loading.setValue(true)

let querylist = [];
querylist.push(fetchClients.trigger());
querylist.push(extractRealClients.trigger());
querylist.push(calculateStatistics.trigger());
querylist.push(fetchClientsPrevYear.trigger());
querylist.push(extractRealClientsPrevYear.trigger());
querylist.push(calculateStatisticsPrevYear.trigger());
querylist.push(calculatePercentages.trigger());
querylist.push(fetchClientDetails1Year.trigger());
querylist.push(extractThreeLastMonths.trigger());
querylist.push(statisticsThreePrevMonths.trigger());

Promise.all(querylist).then(() => {
  console.log("All operations completed successfully."));
}.catch (error) {
  console.error("An error occurred during the process:", error);
}.finally {
loading.setValue(false)
}
function triggerQuery(query) {
  return new Promise((resolve, reject) => {
    query.trigger({
      onSuccess: resolve,
      onFailure: reject
    })
  })
}

async function processClients() {
  loading.setValue(true)
  try {
    await triggerQuery(fetchClients);
    await triggerQuery(extractRealClients);
    await triggerQuery(calculateStatistics);
    await triggerQuery(fetchClientsPrevYear);
    await triggerQuery(extractRealClientsPrevYear);
    await triggerQuery(calculateStatisticsPrevYear);
    await triggerQuery(calculatePercentages);
    await triggerQuery(fetchClientDetails1Year);
    await triggerQuery(extractThreeLastMonths);
    await triggerQuery(statisticsThreePrevMonths);
    
    console.log("All operations completed successfully.");
  } catch (error) {
    console.error("An error occurred during the process:", error);
  } finally {
    loading.setValue(false)
  }
}

// Make sure to call the function to execute the async process.
processClients();
2 Likes

I went with second approach and it seems to work properly I failed one query with intention to see if other queries will be called or not

1 Like

maybe out of context but I want to store jwt in retool where can I save it and make it reusable thanks

Hey @dinkok!

You can store and reuse JWTs in Retool using the provided OpenID Connect (OIDC) integration. This requires either an ID token or access token to be a JWT. Here's how to implement it:

1. Access settings in Retool and navigate to Authentication > SSO.
2. Click on 'Add SSO' and select 'OpenID Connect (OIDC)'.
3. Fill out the required fields that include your application's OAuth client ID and secret, scopes to grant to Retool, and the authorization and token endpoints for your OpenID provider.

Retool will then attempt to decode these tokens as JWTs. Once stored, they're available within Retool to customize applications or control permissions. Access them using {{current_user.metadata.idToken}} or {{current_user.metadata.accessToken}}.

If a refresh token was returned in the initial login flow, it's automatically used by Retool to refresh the tokens every two hours. This can be customized!

Here are some docs that might be helpful:
https://docs.retool.com/sso/quickstarts/custom-oidc

https://docs.retool.com/sso/quickstarts/custom/oidc#thin-tokens-and-fat-tokens

this would require the Enterprise plan right, or is it possible to make the Google SSO act the same way? if it does require the Enterprise plan, does Retool have any other secure built-in storage for JWTs or is the best option still a HttpOnly cookie (local/session storage can be unsafe usually, but that would be for the browser storage and not necessarily the Retool local/session storage... if that makes sense? someone had to point out the difference to me otherwise I'd still think they were the same thing.)