How to retrieve Functions list in Worflows? How to get the name of the called function? #introspection

Hi,

I'm working on a generic monitoring/alert application for my team: a handmade little Grafana or Datadog. The difference is that my application pull data from ressources instead of pushing it like in Grafana and Datadog.

My goal is to convince my team it is easy and convenient to make monitoring and set alerts.

With the Retool architecture I found a way to do that in different parts :

  • a time triggered Workflow that collect data (the one my teammates should edit to add measures) and send everything into BigQuery
  • a time triggered Workflow that do the checks on BigQuery and throw alerts on Slack
  • an app where teammates can add and edit alerts
  • a Retool database to store alerts information (assertion, metricId to check, Slack channel to use...)

That's all for the context :smiley:

My questions are for the Workflow that collect data, it should be edited by the team to add some "measure" queries. I would like this process to be simple and reliable.

The dream for me would be:

Be able to trigger a Function from a string.

For example I have the string "monitor_a" i would like to launch the monitor_a() Function.
For example:

in a js block, to list all available Functions and to be able to trigger them based on their names.

For example : I have functions monitor_a, monitor_b, monitor_c, slack_alert.
I would like in a js block to trigger monitor_a(), monitor_b() and monitor_c().
And if a teammate add a function monitot_xxxx it should be triggered automatically in a for loop without the need to reference it anywhere.

Get the name of Functions

Actually in a js block, function calls seems to be transformed into AsyncFunction I don't know how it works but the fact is that I can't retreive the function name inside the function.




The same inside a JS block, it seems impossible to retreive the Functions name even if we have the Functions Array.


I hope I've made myself clear!

Have nice day :sunflower:

Hi @Floo,

There are probably a couple ways you could get this going, but because Retool doesn't expose a list of functions, you would need to maintain your array (or Object, in this case) manually.

Try the following code and see if it works - this captures the results, which you may or may not care about.

// Instead of an array, create an object with the functions you want to call
let monitors = {monitor_a, monitor_b} //Same as {monitor_a: monitor_a, monitor_b: monitor_b}

// Map over the Object using the key name (function name in this case)
let results = Object.keys(funcs).map(funcName => {
  // Now we're calling the function which is referenced directly in the monitors variable
  return monitors[funcName]()
})
let final = await Promise.all(results) // Since all functions in Retool are async, we have an array of promises
return final //if you want

You could achieve something similar with eval, which is usually frowned upon, so this seems cleaner.

A possible way to not have to maintain the list of functions would be to use standardized names. For example, if your function names were always {monitor_1, monitor_2...,monitor_99} you could loop as many times as needed, creating the function object IF the object exists. Something like this could work.

const monitors = {}
// Adjust loop as needed
for(i = 1; i < 20; i++ ) {
  let fn = `monitors_${i}`
  try {
    monitors[fn] = eval(fn)
  } catch {
    //do nothing
  }
}

// Map over the Object using the key name (function name in this case)
let results = Object.keys(monitors).map(funcName => {
  if(typeof monitors[funcName] === 'function') return monitors[funcName]()
})
let final = await Promise.all(results) // Since all functions in Retool are async, we have an array of promises
return final //if you want

Hi @MikeCB,

Ho that line illuminated my day :slight_smile:
let monitors = {monitor_a, monitor_b} //Same as {monitor_a: monitor_a, monitor_b: monitor_b}
Wonderful!

Thank you for the time you spent for that answer!

The eval solution is interesting but not possible because in this case I prefer to use meaningful names like monitor_01_redirections_count)

Do you think it is a reasonable feature request to ask to Retool to expose functions in js code ?

Thank you again!