dotnetnuke2sxc

Update context.form.runFormulas() from V1 to V2 formulas


2sxc v20 deprecates form.runFormulas() as stated in this alert: "form.runFormulas() is being deprecated and will stop working end of 2024. Use V2 formulas and return the promise. Formulas will auto-run when it completes."

And now documented in https://docs.2sxc.org/abyss/releases/history/v20/breaking.html

Following this previous topic where this need was discussed: 2sxc Run formula when a value from another field changes

How can I convert this formula to v2:

v1(data, context) {
  if (data.Intervention == null || data.Intervention == "") return "";

  if (data.Intervention != context.cache.Intervention) {
    context.cache.Intervention= data.Intervention;
    delete(context.cache.data);
    context.cache.alreadyRun = false;
  }
  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/ReturnIntSpecs/IntProcedure?Intervention=' + data.Intervention)
    .then(data => {
      context.cache.data = data;
      context.form.runFormulas();
    });
}

Principles remain the same. Populate a field with the string content from the IntProcedure API, where another filled field (Intervention) is served as a parameter. This needs to run every time Intervention is selected/changed.


Solution

  • V2 formulas allow the return of complex objects + promises. https://docs.2sxc.org/js-code/edit-form/formulas/v2-return.html

    The only special bit of the work above is

      context.sxc.webApi.fetchJson('app/auto/api/ReturnIntSpecs/IntProcedure?Intervention=' + data.Intervention)
        .then(data => {
          context.cache.data = data;
          context.form.runFormulas();
        });
    

    This bit can simply be replaced with either...

     const promise = context.sxc.webApi.fetchJson('app/auto/api/ReturnIntSpecs/IntProcedure?Intervention=' + data.Intervention)
        .then(data => {
          context.cache.data = data;
          // context.form.runFormulas();
        });
    return {
      promise,
      stop: false,
    }
    

    Not tested, but I believe this would result in the same effect as before.

    But: The code is hard to follow, and relies on various state variables in the cache to hopefully do what you want it to.

    To fully go to v2, you may want to consider making the flow clearer. For example, if you leave out stop: false it would not run any more. This would make sense if your code were processing the result directly in the promise (and returning it as desired.

    You should also check the tutorial examples: https://2sxc.org/dnn-tutorials/en/razor/tut/formulas-dropdowns