Common Code Examples

Use the following libraries and common code resources compiled here to help you write flows. 

Libraries

App Xchange supports the NodeJS v18.15.0 version of JavaScript. 

The App Xchange flow engine supports the following JavaScript libraries:

Day.js

Go to the Day.js library documentation.

V1.11.7

The flow engine supports all methods including the following plugins:

Numeral.js

Go to the Numeral.js library documentation.

V2.06

The flow engine supports all methods.

Lodash

Go to the Lodash library documentation.

V4.17.21

All methods are supported. To call lodash functions, use the standard _.method().

uuid

Go to the uuid library documentation.

V9.0.0

The most common method for generating GUIDs is uuid.v4().



Flow Helpers

The App Xchange flow engine uses the following helper code snippets, created specifically to help you access data when writing flows. Helpers are organized by the namespaces they access:


workspace

info()

Access data of the Flow Workspace: workspace.info()

Access the Workspace id: workspace.info().id

Access the Workspace name: workspace.info().name


appNetwork

fileUrl(fileId: string) 

Generate an App Network file url: appNetwork.fileUrl('fileGuid')

legacyFileUrl(fileId: string)

Generate a Legacy App Network file url: appNetwork.legacyFileUrl('fileGuid') 


flow

info()

Access flow info: flow.info()

Access the flow registration ID: flow.info().registrationId

Access the flow URL: flow.info().url

config

Access the flow's config: flow.config

Access a property on the flow's config:  flow.config.myProperty || flow.config[myProperty]

loopItem()

Access item data (only available for a For Each in a List step): flow.loopItem()

mapItem()

Access item data (only available in the context of mapping data in a Map step or Connector Action step): flow.mapItem()

trigger

Access the flow's trigger event: flow.trigger.event

Access the flow's trigger data: flow.trigger.data

Check if the flow run was triggered by a cache record create event: flow.trigger.isCacheCreate()

Check if the flow run was triggered by a cache record update event: flow.trigger.isCacheUpdate()

Check if the flow run was triggered by a cache record delete event: flow.trigger.isCacheDelete()

Check if the flow run was triggered by an action closed out as successful: flow.trigger.isActionSuccess()

Check if the flow run was triggered by an action closed out as failed: flow.trigger.isActionFail()

step(stepId: string)

Access a property on the output data of a previously executed step: flow.step("step-id").output.JobCode

Access the action response of a previously executed step: flow.step("step-id").actionResponse

Access the action request of a previously executed step: flow.step("step-id").actionRequest

Check if a previously executed step has an action status of Success: flow.step("step-id").isActionSuccess()

Check if a previously executed step has an action status of Fail: flow.step("step-id").isActionFail()

Check if a previously executed step has an action status of Queue Action Success: flow.step("step-id").isQueueActionSuccess()


Dates

return today’s date

use Vista standard formatting for Batch creation

Note: Will set to 1st day of current month.

compare a date to the current day

create a date variable, set it equal to an input value, and output it in a specific format

safely convert a value to a date, or default to today’s date

calculate the next closest Friday after a given date

Note: Replace the example date with your date variable.

calculate the last day in a month

calculate the last day in a week

compare two dates

Strings

know if a string contains specified text

find the first position of a specified value

Will return a -1 if not found.

convert to upper or lower case

Note: You should convert to lowercase or uppercase prior to string comparison! For example, converting an email address, vendor name, or payment type name to lowercase prior to comparison will make it case-insensitive and protect you against capitalization errors.

Lodash also gives us the following:

return the length of the string

delete or keep part of the string

Javascript has a substring() method, but we recommend slice(). You can read why here if interested.

slice() takes a startIndex and an optional endIndex and returns the string between the start and the end indexes. 

If no endIndex is supplied, slice() preserves thru the end of the string. 

This is non-destructive. It returns a new string from the start index to the end index while leaving the original string intact. vTest remains unchanged. You will have to assign this to a new variable in order to access it.

replace all instances of a string with another

Use replace to strip out special characters. It is a great and easy way to make sure your string is sanitized and does not contain special characters that can cause problems.

Non-destructive

remove starting and ending white space

Trim should be one of the most common functions used with strings. Be sure to use it to get rid of any leading or trailing whitespace that can cause issues. Whitespace has been known to cause support tickets and delays in onboarding, and is very tough to track down. Use Trim and eliminate this headache!

evaluate if a value is blank or null

Always check for null or empty prior to using the value. You can then create a hierarchy of data, for example, checking allocation fields first and if blank/null then checking the expense detail fields and if blank/null then defaulting to something. This type of defensive coding will keep flows from failing or remediation tasks from being created for missing data.

format data as currency

split a string into parts

As with previous JS string methods, these are non-destructive to the original string and must be assigned to new variables.

If the string does not contain the character or string you are splitting on, it returns undefined.

add characters to the beginning or ending of a string

Numbers

parse a number from a string

format a number into dollars

Arrays

create a hardcoded array, e.g. for use with the In operator in a filter expression

Use extreme care when hardcoding something. Make sure it is future proof and will not need to be changed in the future.

determine if any element in an array contain a value matching the criteria

determine if all elements of an array contain a value matching the criteria

sort an array by a column in descending order and then return the first value (highest value).

sort() mutates the original array. The default sort order is ascending. The time and space complexity of the sort cannot be guaranteed as it depends on the implementation. 

Lodash is another option:

evaluate if a lookup step had any records

How to access element in lookup

map a filter step's output array

add each value in an array to a list or a string

sum all values in a field of an array or list

The reduce() method executes a user-supplied "reducer" callback function on each element of the array, in order, passing in the return value from the calculation on the preceding element. The final result of running the reducer across all elements of the array is a single value.

The first time that the callback is run there is no "return value of the previous calculation". If supplied, an initial value may be used in its place. Otherwise the array element at index 0 is used as the initial value and iteration starts from the next element (index 1 instead of index 0).

Learn more

assign a value based on looking up a value in an array

do something for each item in an array

sort the Input for a MAP step, to intentionally order lines in an invoice

Remember sort() will mutate the original array where as _.orderBy() will return a new array.

Other Helpful Coding Tips

create two lists and then find the values from one that doesn’t exist in the other

use null coalesce (double question marks)

These are both the same

How to fix if node does not contain something

Note the . before ["Concur_Approver"]

use regex for any file containing “KPC” and ending in .CSV

call a configured variable

reference a configuration property set as multiple text items

check if the Config Value is empty

create a map step without any input

Set “List or Object” [] or {}

dynamically determine start row for a Parse Delimited File step

You have to edit the JSON of the flow, but then you can change the property to any value you want.  Must resolve to a number.

StartingRowNumber: 

create a random string

TryParse

set the field to get data from via a configuration

This is helpful if you want to be able to use a configuration on a shared flow so that you can set a different ud field to reference for each customer.

Everything inside the brackets is just a string value, so this method can be used in a number of ways.

You could also create other dynamic situations.