Extending App Connect: Formatters

Writing your own Formatters

Formatters are used in expressions like a method for a specific data type. The data types available in App Connect are array, boolean, null, number, object, string and undefined.

Using the formatter in an expression is done like {{ "Hello World".uppercase() }}, using the formatter on a type that is not a string will result in a warning in the console and the formatter will return undefined. So {{ (123).uppercase() }} will return the warning Formatter uppercase in expression [(123).uppercase()] doesn't exist for type number and will return undefined, this is because 123 is a number and not a string.

Formatters are sync, you can’t use async functions.

Syntax

dmx.Formatter({data type}, {formatter name}, {formatter function})
dmx.Formatters({data type}, {object with formatter name as key and function as value})

The first argument of the formatter function is always the value where it was added on, the other arguments are the ones passed as the arguments in the expression. For example a formatter function for append will use function(str1, str2), in the expression {{ "Hello".append(" World") }} str1 will be Hello and str2 will be world.

Samples

Here is how the full append formatter looks like:

dmx.Formatter('string', 'append', function(str1, str2) {
  return str1 + str2;
});

Adding multiple formatters:

dmx.Formatters('number', {
  'add': function(a, b) {
    return a + b;
  },

  'substract': function(a, b) {
    return a - b;
  }
});

Special Global Formatters

There are some formatters defined as type global, they are currently not available from the UI in Wappler. The global formatters are like functions and called like {{ run(flow, param) }}. The run formatter is used when you add a flow to an event handler.

Other already available global formatters are json and log, they are not available in the UI but are included in the App Connect source. The json formatter converts an object to a json string and the log formatter logs the object to the console, this can be handy for debugging your data.

Here is how the log formatter looks like:

dmx.Formatter('global', 'log', function(obj) {
  console.log(obj);
  return obj
});

Advanced formatters

Sometimes you want to do more advanced operations like looping over data and using a subexpression to manipulate that data. The this object references the component where the expression is runed from. The components are seen as scope objects that contain their own data and references their parents. I will not go deep in on how the component is working, but we will use it to create a new data scope for our subexpressions.

Here a sample for a map formatter:

dmx.Formatter('array', 'map', function(arr, expr) {
  var scope = this;
  arr = dmx.repeatItems(arr);
  return arr.map(function(item) {
    return dmx.parse(expr, new dmx.DataScope(item, scope));
  });
});

The formatter works like {{ [1,2,3].map('$value - 1') }} and it will return [0,1,2].

The first argument arr is the input array [1,2,3]. The function dmx.repeatItems will convert this array, the items will become objects like { $value: 1, $index: 0 }. If the input item was an object it will keep its properties like with the repeater component.

The arr.map is the native Array.map method. In the callback function we return the result of the subexpression as the new value. We use dmx.parse to parse the expression that was given as a string to the formatter. The second parameter for on dmx.parse is the scope it should work on, when not given it will use the app scope. We create a new scope with our current item and use the component scope as the parent.

Community Page
Last updated: