isFetching JS query property not working (value is "false" when running the query all the time)

Goal: Using the isFetching property from a JS query to condtionally display UI elements

Steps: Implemented the sample from the web app tutorial (Web app tutorial | Retool Docs) and trying to react on the isFetching property from the blockAll query (conditionally displaying a UI element)
When running the query isFetching is not getting the value "true", it remains "false".

Details:
Here is the code for the blockUsers JS query which I implemented:

return (async () => {
var rows = table1.data;

const unblockedUsers = rows
  .map((row, index) => [row, index])
  .filter(([row]) => !row.blocked);

let blockIndex = 0;

const blockNext = () => {
  // Notify and quit when finished
  if (blockIndex >= unblockedUsers.length) {
    utils.showNotification({
      title: "Success",
      description: "Successfully blocked " + unblockedUsers.length + " users.",
      notificationType: "success",
      duration: 3,
    });

    // Update table after queries finish

    getUsers.trigger();
    
    return;
  }

  // Get next unblocked user and unblock them
  const [unblockedUser, index] = unblockedUsers[blockIndex];
  statusText.setValue("Blocking user " + unblockedUser.name);
  blockAllUsers.trigger({
    additionalScope: { i: index },
    onSuccess: function () {
      blockIndex++;
      blockNext();
    },
  });
};

blockNext();
})();

I've tries both, embedding it in "return (async () => {...}) " and without. When trying to use the isFetching property from the JS query I ran into the problem that isFetching is not set to true when running the query. The value remains "false" all the time. Conditionally displaying a UI element based on that isFetching property is therefore not working as it never updates to "true".

Why is isFetching not working?

Hey @Sebastian_83, this is the expected behavior of JS queries in Retool. If you take a look at the debug tools in the app, you'll likely see that your JS query returns very quickly. I touch on this a bit in my post on asynchronous JS in the asynchronicity in action section.

Even in my async code, where I'm awaiting the return of the asynchronous API calls, the JS query returns in .005s. Which is too fast for the update on isFetching to give us any meaningful information.

The only way to make that JS query wait for all code to finish before it returns (and therefore give you the value for isFetching that you are looking for) is to create promise objects from the async calls and then resolve them before / when returning.

In my promises code, the JS query's isFetching property is true for the 4.6s in which that query runs.
CleanShot 2024-04-08 at 11.53.14@2x

Hope this helps!