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 is 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.
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 instances of the same type. You might notice that java.util.Date
does not have a year attribute, but today.year
still works because JavaScript
will automatically invoke the appropriate get method.
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 does not conform to JavaScript naming convention,
for example if it starts with a digit, such as 7Monkeys
, you can
refer to it as this["7Monkeys"]
. It is not 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".
"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 you for your 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.