Handle undefined variable and error when you pass a variable to a query

I don't know if this was suggested before, but I think I worked out a way to pass additionalScope variables to queries without causing the linting errors.

In some queries, I already have variables that load from temporary states and which make use of the optional chaining operator.

I figured that instead of passing vars to queries via additionalScope, why not just set those vars to temp states and reference them in the query config?

To keep it neat, I created a new state called queryVars (or whatever name you choose), where I will be setting whatever vars needed inside an object named the same as the query name (for convenience).

retool_query_vars_tempstate2

So I changed my code from this:

addRequestExpense.trigger({
  additionalScope: {
    amount: inputMileageExpense.value,
    type: "expense",
    subtype: "mileage"
  },
  onSuccess: function(data){
    inputMileageExpense.resetValue()
  }
});

To this:

var amount = await queryVars.setIn(["addRequestExpense", "amount"], inputMileageExpense.value);
var amount = await queryVars.setIn(["addRequestExpense", "type"], "expense");
var amount = await queryVars.setIn(["addRequestExpense", "subtype"], "mileage");

addRequestExpense.trigger({
   onSuccess: function(data){
    inputMileageExpense.resetValue()
  }
});

And then in my query, I just reference the temp state, instead of the actual (linting error-inducing) var:

{{queryVars.value?.addRequestExpense?.amount}} <== {{amount}}

I suppose there may be some tradeoffs with this approach, but if the linting errors bother that much, maybe it could be a solution.

I was going to say that for more flexibility, it could be improved slightly by assigning the query name to a variable, in case you need to change the query name in the future and don't want to manually update it in several places.

var queryName = "addRequestExpense";

var amount = await queryVars.setIn([queryName, "amount"], inputMileageExpense.value);
var amount = await queryVars.setIn([queryName, "type"], "expense");
var amount = await queryVars.setIn([queryName, "subtype"], "mileage");

addRequestExpense.trigger({
   onSuccess: function(data){
    inputMileageExpense.resetValue()
  }
});

But then you would still need to update the query name in two places. Wouldn't it be even better to update it only in one place? That's possible also!

var queryName = addRequestExpense;

var amount = await queryVars.setIn([queryName.id, "amount"], inputMileageExpense.value);
var amount = await queryVars.setIn([queryName.id, "type"], "expense");
var amount = await queryVars.setIn([queryName.id, "subtype"], "mileage");

queryName.trigger({
   onSuccess: function(data){
    inputMileageExpense.resetValue()
  }
});

Thus, when you need to use this code for other queries, simply change the query name on the first line and everything flows from there.

:muscle: :beers:

1 Like