I have a table in Retool that includes a column of buttons. The functionality I want to achieve is as follows:
- Button Behavior: Each button in the column should be disabled or enabled based on the output of an API call.
- API Response Logic: If the API returns no output (an empty result), the corresponding button should be disabled. If the API returns a valid result, the button should be enabled.
- Dynamic Versions: The API requires a dynamic version parameter to be passed. Each row in the table contains a
version
column, which needs to be sent to the API for that specific row.
- Iterating Over Rows: I need to iterate over all rows in the table, passing the respective
version
for each row to the API. The button for that row should update its disabled state based on whether the API returns a result for that specific version.
My Questions:
- What is the best way to handle this kind of functionality in Retool?
- What Retool queries or components can I use to:
- Fetch the version for each row.
- Trigger the API for each row.
- Dynamically enable or disable the button based on the API response.
Challenges:
- I need to ensure that the API is called for every row in the table using its respective version.
- The table has multiple rows, so I need an efficient way to loop through the rows, call the API, and update the button states in real-time.
I’m looking for guidance on the best approach to achieve this. Should I use a combination of Retool queries, JavaScript, and temporary state to manage this process? Any examples or insights would be greatly appreciated!
2 Likes
Hi @Javith_Mohamed, Welcome to the Retool community.
You can set a temporary state for the enable/disable button in the column using the Query transformer. In the column, you can conditionally check the key's value—if it is true, the button will be enabled; otherwise, it will be disabled.
2 Likes
Hi @ZeroCodez,
Thank you for the warm welcome! I need a bit of clarity regarding the setup for the temporary state and the transformer in Retool. Here’s my current implementation, and I would appreciate your feedback on whether it meets my requirements.
Requirement Overview
I have a table (table4) with a column of buttons, and I want the enable/disable functionality of these buttons to be driven by an API response. Specifically, for each row in the table, I need to:
- Fetch Data: Trigger an API query (query15) to get the status for each version specified in the paletteVersion column of the table.
- Store Results: Based on the API response, store the results in a temporary state (tempState1), which will determine whether the button for each row is enabled or disabled.
- Disable Buttons: If the API returns no relevant data for a version, the corresponding button should be disabled.
Current Implementation: API Query:
Params:
additionalScope: {version}
Transformer Query:
Here’s the transformer function I’ve set up:
async function fetchVersionData() {
const results = await Promise.all(
{{ table4.data }}.map(async (row) => {
const version = row.spec.Version;
return await {{ query15.trigger }}({
additionalScope: { version },
onSuccess: (data) => data,
onFailure: (err) => {
console.error(`Query failed for version ${version}:`, err);
return null;
}
});
})
);
{{ tempState1.setValue(results) }};
return results;
}
return fetchVersionData();
Temporary State
- Initial Value: The initial value for tempState1 is set to an empty array: .
Button Configuration
In the button's disabled property within the table, I check the corresponding result in the temporary state:
{{ !tempState1.value[row.index] }}
Questions/Concerns
- Is this implementation correctly fetching and storing the version data?
- Does the use of tempState1 for button states align with Retool's best practices?
- Is there anything else I should consider to enhance this setup?
Thank you for your guidance!
1 Like
Do you have separate APIs for the table and the button?
1 Like
Hi @ZeroCodez,
Thanks for the follow-up! To clarify, for the table, I am using a MongoDB resource to populate the data. However, for the enable/disable functionality of the buttons, I need to use a separate API resource. This API is triggered dynamically based on the Version
present in each row of the table.
1 Like
Is it possible for you to retrieve all the data from the API, match the version with the MongoDB data, and then add an additional key for the enable/disable button?
1 Like
Retrieve all data from the API is not feasible for my case because the data size is large. Instead, I can only retrieve data for a single version at a time. Due to the volume, fetching all records at once would not be efficient or possible.
1 Like
You can use a JavaScript query to call an additional API to retrieve the button status. In the JavaScript query, you can loop through your initial query to call the extra API, similar to what you did in the transformer, and add a dynamic key called buttonStatus
to store the value. However, calling an additional API for each item will increase the loading time.
2 Likes
Hi @Javith_Mohamed
Just wanted to check in and see if this was something you're still working on?
2 Likes
Hi @AbbeyHernandez Yes, do we have a solution for this?
1 Like
Hi Javith. I would be curious about a few things
- Roughly how many rows of this table are we going to have coming from mongodb? And we need to query the api for each of them right? How many versions exist? Are they repeated often? like maybe there are 3000 rows from mongodb but only 15 versions so we could just request the 15 versions so we only have to do 15 api calls?
- maybe we need to make sure not to send too many queries at once? Doing promise.all like you have above might mean firing off all those rows of requests at once which i think retool might not handle well.
- This will happen just once at page load? so the steps will be
a. page shows nothing
b. load data from mongodb, for each item, query api, then once we have all results, show the data on the screen with each button enabled or disabled?
1 Like