Functions
Last updated
Last updated
With functions, you can express advanced conditions or calculations using JavaScript. The JavaScript code is sandboxed and has read-only access to the data sources defined as parameters.
There are two main use cases for functions:
As a function property on an Object Class or a Data Source
As a data value used in Action Nodes and UI Components
Function properties are runtime-calculated values on an Object Class or a Data Source. You may reference other properties on the same Object Class or Data Source. For function values on Data Sources, you may also reference properties in other Data Sources, as well as the Data Sources themselves. Data Sources with cardinality many
become arrays, allowing you to do (read-only) array operations, such as iterations.
This screenshot shows the All Users Data Source with a filter including only users missing a value on the Phone property.
The screenshot below shows the function editor accessed from a function property on an object class.
Self Properties: Properties on the same Object Class or Data Source. This section is only available when defining functions on data sources or object classes (e.g., a calculated function property, such as the example below).
App Data: This is all the variables and data sources of your App Data (or Service Data). You may add whole data sources as function parameters (will give you an array of objects as a function parameter), or you may add a data source property or App Variable as a function parameter (will give you a constant as a function parameter).
Code Editor: This is where you write code (JavaScript).
You may write as much code as you want, but the code should return some value(s) depending on where you use the function editor. In the below example, we return a string (since the function editor is used for calculating a display property). If the function editor is used to calculate a Visibility Condition, it should return true
or false
.
The added Function Parameters that may be used in the Code Editor.
When adding a data source as a function parameter, it is an array of objects. For example, by adding projects
as a function parameter, you may perform array operations such as projects.length
, or you may access properties of the data source (for example, the title of the first entry: projects[0].title
). The added function parameters are read-only.
Context or Breadcrumb. It helps you keep track of the context of what you are defining a function for. In the example below, we are defining a function for a data source property. If we were defining a function for a visibility condition on a container, the breadcrum (path) to the UI Component would be displayed.
Search your App Data. Makes it easier to locate a property or data source.
Menus for accessing Enumerated Types or JavaScript libraries to add as Function Parameters. You may add all enums from the Global Data Model or the built-in enums (such as Language). You may add built-in JavaScript libraries such as Math.js.
Apply Changes. You may save your function without exiting the editor.
Note that you may use Find and Replace inside the code editor and that the editor has code completion and code suggestions.
You can use data value functions to return any value type needed. You may include parameters from all available Data Sources, as well as the external libraries.
Here are some examples of how to use functions to create custom return values.
A welcome message adjusted to the time of the day, using the moment.js library:
Concatenate a person's firstName
and lastName
to a full name value:
Check the value of an Enum variable:
Here, activeEnvironment
is added from the App Variables, while production
is added from the built-in enums from the Enum Constants menu (marked as number 7 in the figure above).
The function editor includes a set of external libraries providing advanced functionality.
Math.js is a math library. Visit mathjs.org for more information.
Moment.js is a library to parse, validate, manipulate, and display dates and times. Visit momentjs.com for more information.
Here are a few examples (remember to add moment.js as a function parameter first):
Note that it is necessary to convert the returned moment.js
object into a Datetime data type. We do that using the .toJSON()
function.
Numeral.js is a library for formatting and manipulating numbers. Visit numeraljs.com for more information.
Inside Apps, you may use other external JavaScript libraries in addition to these (i.e., client-side javascript libraries). You may add them to the Custom Header Tags section of App Settings. Once added, you will be able to reference that JavaScript inside the Function editor. However, the autocomplete and code validator will not recognize the reference to the external libraries in the editor, but this warning may be ignored.
Functions can be used to handle advanced logic, like data iteration, creation of complex strings, etc., using JavaScript.
Below are some examples of common use cases for functions and matching JavaScript code. JavaScript ES6 syntax is used in many of the examples. Semicolons are optional.
null
or undefined
By default, all properties in Appfarm (and JavaScript in general) are undefined until a value has been assigned. It may then be blanked (set to null).
The traditional way of handling whether an integer property myProperty
is null
or undefined
is:
It can be simplified to:
Or, a one-liner:
This means: if myProperty
has a value, return myProperty
, otherwise return 0.
You want to create a string containing static text combined with property values. For example, to generate a dynamic welcome message, interpolating the values of the function parameters firstName
and companyName
.
This example uses backticks (`
) at the start and the end. Inside the backticks, you can substitute strings using placeholders (${propertyName}
). The result is a merged string with line shifts preserved. This concept is known as template literals in JavaScript.
You have a data source Companies
containing all companies, and you want to create a condition that evaluates to true if there are any active companies in this data source. A function parametercompanies
is added, with a filter state EQUALS active:
Or, as a one-liner:
You have a data source Companies
with cardinality many
. Companies are added as a function parameter, with a filter applied, resulting in this array containing 1 or 0 objects. You want to return the property Company Name
if the filter resulted in an object, and null
otherwise:
Or, as a one-liner:
Good to know
When adding whole data sources as function parameters, they are treated as arrays inside the function editor, as in the above example. However, you cannot to refer properties more than one level deep. In other words, if you add Contacts
as a function parameter, you cannot access contacts[0].company.name
.
In this case, you need to add a runtime property (function) to the Contacts
data source (for example companyName
, returning Contacts.Company.Name
) and refer to this property as Contacts[0].companyName
.
You have a data source Order Lines
and need a property Company
on this data source. However, Company
is located at Order Lines.Order.Company
.
The solution is to create a runtime property on the Order Lines
data source, with data type Company, and property type Function. Add Order Lines.Order.Company.ID
as a function parameter:
Note that if you add an array as a function parameter, and want to access the built-in ID property of an object, you need to use Node Name, which is _id
.
You have added salesLines
as a function parameter, an array containing all relevant sales to be accumulated. You want to sum the Amount
property of the sales. When referring to properties of an array added as a function parameter, you need to use the Node Name (as defined in the object class properties) of this property. In our case, the Node Name of Amount
is amount:
If amount
could potentially be undefined or null, we could handle that as follows:
You have added salesLines
as a function parameter, an array containing all sales. You want to filter only those with a positive amount
, and save this array to a new array salesLinedFiltered
.
Note that in this example, you would typically just apply a filter to the function parameter salesLines
(with the expression amount >= 0
). This code sample is just to demonstrate the filter method of JavaScript arrays.
You have a Companies
data source, with a property Company Name
(Node Name: companyName
). You want to return a comma-separated list of all company names. For this, we need to convert the array of objects to an array of strings, and then join the strings with a comma.
You have a Companies
data source, with the properties companyName
and organizationNumber
. You would like to convert this to a list of objects with the properties name
and orgNo
. This might be used in a service (as the custom response body of an endpoint) when you want to return a list of objects with property names according to some specific cases, or with only a small set of properties from the Companies
data source.
You have an endpoint that returns data to an external system. There are two data sources, Orders
and Order Lines
, and you would like to return a list of orders and, for each order, a list of related order lines.
You have a data source Orders
and want to return the Order Date
(Node Name: orderDate
) of the first order.
Note that in this example you could just use the Sort objects action node on the Orders
data source (sorted Ascending
by Order Date
) prior to adding it as a function parameter, and having a function return orders[0].orderDate
.
When using the Function editor, you may add an App Variable or property of a data source as a Function Parameter. Do not try to update the Property directly from the Function editor, Coded Component or Run Code. When adding an App Variable or the property of a Data Source as a Function parameter, a warning is displayed. The same applies if you e.g. add a Data Source as a Function parameter, and then try to modify a property of that data source through code.