0

I am using tableau js api and calling worksheet.applyFilterAsync & workbook.changeParameterValueAsync methods based on certain conditions. These methods have an otherwise error handler.

I am also in between the executing flow return my custom promise like

      return new Promise((resolve, reject) => {
        resolve(true)
      });

the issue is when i am returning promise and not changeParameterValueAsync or worksheet.applyFilterAsync i am getting an error

TypeError: undefined is not a function (near '...}).otherwise(function (err) {...')

looks like the promise i return does not have a otherwise error handler?

relevant code is as follows

  const applyStep = (step) => {
    if(step.step_type == 'filter') {
      return worksheet.applyFilterAsync(step.name, values, 'replace');
    } else if(step.step_type == 'parameter') {
      return workbook.changeParameterValueAsync(`${step.name}`, value);
    } else {
      return new Promise((resolve, reject) => {
        resolve(true)
      });
    }
  };


  const applyFilters = (counter) => {
    return new Promise((resolve, reject) => {
      let filter = filters[counter];
      if(filter) {
        applyStep(filter).then(promiseTimeout(filter.delay)).then(() => resolve(applyFilters(++counter))).otherwise(function(err) {
          reject(err);
        });
      } else {
        resolve(true);
      }
    });
  };

I need the otherwise error handler to handle error returned by tableau api methods but it does not work in cases where i am returning my custom promise, may be because the promise i am returning does not have an otherwise error handler?

How can address this any help in fixing this will be really great, Thanks.

opensource-developer
  • 2,826
  • 4
  • 38
  • 88
  • 1
    Is it really "otherwise"? In promises, error handling is usually done with `.catch()`. – C14L Nov 05 '20 at 17:34
  • @C14L Seems like it: https://help.tableau.com/current/api/js_api/en-us/JavaScriptAPI/js_api_ref.htm#promise_class – 3limin4t0r Nov 05 '20 at 17:42
  • 1
    Avoid the [`Promise` constructor antipattern](https://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-antipattern-and-how-to-avoid-it)! – Bergi Nov 05 '20 at 20:25
  • After purging the Promise constructor anti-pattern, `return Promise.resolve(applyStep(filter)).then(...).then(...);` should get you out of trouble by recasting the tableau promise as a native promise. – Roamer-1888 Nov 06 '20 at 19:18

2 Answers2

2

From the tableau docs:

otherwise(errback: Function) Promise Registers a rejection handler. Shortcut for then(null, errback).

So in your code, you could do

applyStep(filter)
.then(promiseTimeout(filter.delay))
.then(() => resolve(applyFilters(++counter)))
.then(null, function(err) {
    reject(err);
});

That is instead of .otherwise(err) you can use .then(null, err).

C14L
  • 12,153
  • 4
  • 39
  • 52
1

The issue is that you are currently mixing two different types of promises. The tableau Promise and the standard JavaScript Promise. These two have different methods which currently results in issues. You can pass a tableau Promise to Promise.resolve() to convert it into a standard JavaScript Promise.

return Promise.resolve(worksheet.applyFilterAsync(step.name, values, 'replace'));

When working with the promise you now have to work with then(), catch() and finally() instead of then(), otherwise() and always().

3limin4t0r
  • 19,353
  • 2
  • 31
  • 52