Can I run an if statement inside a calculated field?

I’m using retool to run a custom e-commerce store. In my retool table, I have a calculated field where I calculate the number of days remaining to ship each item.
I added a new feature where users can choose between standard and express shipping on checkout.
I’m wondering if I can run an if statement in the calculated field to check what type of shipping the user selected and then run the calculation based on that field.
It would look like this :
Current calculation:
Math.floor( (new Date( moment(currentRow.date) .add(9, "days") .format("l") ).getTime() - new Date(moment().format("L")).getTime()) / (1000 * 3600 * 24) );
The Calculation I want to make:
if(currentRow.shipment_type === 100){ Math.floor( (new Date( moment(currentRow.date) .add(9, "days") .format("l") ).getTime() - new Date(moment().format("L")).getTime()) / (1000 * 3600 * 24) ); } else if(currentRow.shipment_type === 200){ Math.floor( (new Date( moment(currentRow.date) .add(3, "days") .format("l") ).getTime() - new Date(moment().format("L")).getTime()) / (1000 * 3600 * 24) ); }

1 Like

@tono-martinez-baez the easier way to do this is to use the JS ternary operator, so something like:

currentRow.shipment_type === 100 ? Math.floor( (new Date( moment(currentRow.date) .add(9, "days") .format("l") ).getTime() - new Date(moment().format("L")).getTime()) / (1000 * 3600 * 24) ) : currentRow.shipment_type === 200 ? Math.floor( (new Date( moment(currentRow.date) .add(3, "days") .format("l") ).getTime() - new Date(moment().format("L")).getTime()) / (1000 * 3600 * 24) ) : null

Works Perfectly !!! Thanks!!

It would be nicer if transformers could take input, i.e. function parameters. Then this code could be extracted into a transformer and the field would simply make the function call.

1 Like

Ternary operators can get messy for large expressions. A nicer way is to use an immediately-invoked function, this way you can also use js statements as opposed to only js expressions. This can also be more performant if you need to read multiple properties from an expensive object.

{{ (function () {

const item = formatDataAsArray(largeQuery.data).find( ... )
if (item) {
  return `${item.x} - ${item.y}`
} else {
  return "select x and y from the dropdowns above"
}

})() }}

Without the self-invoking function this would need to run formatDataAsArray(largeQuery.data).find( … ) three times.

formatDataAsArray(largeQuery.data).find( ... )
  ? formatDataAsArray(largeQuery.data).find( ... ).x + " - " + formatDataAsArray(largeQuery.data).find( ... ).y
  : "select x and y from the dropdowns above"

Ideally, there would be a way to define functions on a per-app basis similar to transformers. First class JavaScript functions (with workaround)

1 Like