Search code examples
2sxc

2sxc Run formula when a value from another field changes


I created a simple table with two types: CarBrand, with entity data type, selecting the brands from another data. CarModel, with the string dropdown type. I need an API to return the models for each brand, with a custom function I will design.

I'm trying to use the documentation example for filling dropdown values from the API.

function v1 (data, context) {
  if (context.cache.data) return context.cache.data;
  
  if (context.cache.alreadyRun) return data.value;
  context.cache.alreadyRun = true;

  context.sxc.webApi.fetchJson('app/auto/api/ReturnCarInfo/CarModelsForBrand?Brand=' + data.CarBrand)
    .then(data => {
      const lines = Object.keys(data)
        .map(k => k + ":" + data[k])
        .join('\n');
      context.cache.data = lines;
      context.form.runFormulas();
    });
}

data.CarBrand will return the Guid (or array, depending), which is the only thing we can get from an entity data type, so it's fine. The API will deals with this.

What I need is to run this function again every time the dropdown for brands changes. Or basically when data.CarBrand changes value.

These lines would need to adapt, but I have no idea into what.

if (context.cache.data) return context.cache.data;
if (context.cache.alreadyRun) return data.value;
context.cache.alreadyRun = true;

If I remove them "context.form.runFormulas();" would create a loop.


Solution

  • As of now your code will

    1. Not run if the data already exists in the cache to speed things up
    2. Not run if it has already started

    You manage this using some values on the cache - .data and .alreadyRun.

    What I believe you should do is add a check before that, which resets these switches in case the other value has changed. something like this:

    function v1 (data, context) {
      if (data.TheFieldICareAbout != context.cache.TheFieldICareAbout) {
        context.cache.TheFieldICareAbout = data.TheFieldICareAbout;
        delete(context.cache.data);
        // OR this: context.cache.data = null;
        context.cache.alreadyRun = false;
      }
      // now continue with your original code.
      if (context.cache.data) return context.cache.data;