Composite JavaScript

Composite DataSources have a JavaScript tab in addition to the Data tab and the diagram. Any scripts written in this JavaScript editor will be executed once when the Composite is about to begin processing. Therefore, this is a good place to define any functions and import any standard JavaScript libraries that you want to use throughout your Composite flow. All other JavaScript locations, for example in Derivatives and Filters etc. will execute once for every record that flows through them. It is inefficient to keep defining the same function over and over again, so move the functions themselves into the JavaScript tab and then just call the functions from the processors as needed.

For example, to filter a set of records so that only those with a SaleDate equal to today's date are retained, it would be useful to have an isToday(date) script. Here's one that can be put in the Composite JavaScript tab:

function isToday(date)
{
  var today = new java.util.Date();
  return today.year==date.year &&
	today.month==date.month &&
	today.day==date.day;
}

This function can now be called from inside a filter processor by choosing When type JavaScript with a Condition of isToday(SaleDate). Where SaleDate is the name of the field holding the date value for testing.

Note

Fields of date type are actually java.util.Date instances. These are different from JavaScript Date instances - you need to make sure you are comparing like-with-like. You might notice that java.util.Date doesn't have a year attribute, but today.year still works because JavaScript will automatically invoke the appropriate get method for us.

Within a Composite processor script it is possible to refer to the fields of the current record by name, for example SaleDate in the example above. If the field name doesn't conform to JavaScript naming convention, for example if it starts with a digit, like 7Monkeys, you can refer to it as this["7Monkeys"]. It isn't possible to refer to the fields in the Composite JavaScript tab, because this code is executed before the first record is read.

Within a Composite processor script it is also possible to refer to other processors by name (providing the name is unique). You can use this technique to lookup results from parallel flows or processors and incorporate them into your record sequence. The easiest way to describe this is through an example.

Suppose we have a data source called Countries with the following structure:

Code,EN,FR
UK,United Kingdom,Le Royaume-Uni
SG,Singapore,Singapour
US,United States,Les Etats-Unis
MY,Malaysia,La Malaisie

This could be from any kind of data source, but a Tabular DataSource is probably the simplest to create. Create a Composite DataSource and then drag and drop Countries onto the diagram. Now we repeat the process with another datasource called Source with this structure:

Name,Location
Jon,UK
Shih Hor,SG

Drop Source onto the diagram as well. Now create a new Derivative and connect it so the records will flow Source -> Derivative -> Result. Leave Countries unconnected. Now open the Derivative and create a new field called Location (which will overwrite the existing one) with the following value:

Countries.lookup("Code",Location,"EN");

View the result and you will see the Location changes from "UK" to "United Kingdom" because of the lookup.

The syntax of lookup is:

ProcessorName.lookup(field1,value,field2);

The function looks up the first record where field1 contains value and returns the corresponding contents of field2. Null will be returned if it is not found. In our example, we lookup in the "Code" column for a value "UK" and return the value of the "EN" column, which is "United Kingdom" (UK in English). If we wanted the French name, we would lookup("Code",Location,"FR"); and get back "Le Royaume-Uni".

Note

"Code" and "EN" are strings, but Location is a field - be sure not to quote it, it will be substituted with the Location value of the current record when the function is invoked.

You can now combine JavaScript lookups with other features, such as Dynamic Parameters to create:

Countries.lookup("Code",Location,"${Language#choice(EN,FR)#EN}");

which prompts the user for their chosen language (EN or FR) once and then proceeds to use the chosen language substitution for each record encountered.

Lookup works with any uniquely named processor, not just data sources. This means you could perform an operation on Countries before looking up the value). As with field names, you can use this["7thProcessor"] syntax to reference processors with non-conformant names.