Property Path

One of the most important parts of working with RecordInFlight instances is making it as easy as possible to read from and write to the record, without losing the ability to do complex and sophisticated behaviors.

To solve this we have created a specific syntax that we call a “property path”, which is inspired by XPath and JSONPath. A property path describes one or more locations within a record’s data properties.

Property path notation is intuitive:

recordInFlight.getPropertyValue('Parent.Name'); // returns a single Name
recordInFlight.getPropertyValues('Contacts[*]'); // returns a collection of rich objects
recordInFlight.getPropertyValues('Contacts[*].FirstName'); // returns a collection of FirstName values
recordInFlight.getPropertyValues('Contacts[0,1].FirstName'); // returns a collection containing the FirstName value of the first and second Contacts

There are a number of methods on RecordInFlight that allow you to use a property path to read or write information. For advanced use cases and maximum flexibility, you can skip those methods and work with the backing data store directly: Property Node

Two Formats of Property Path

The official, formal definition of a property path is a List<String> where each element is one of two types: a “field” or a “selector”. A “selector” follows a list and specifies which items from that list we want to work with.

// field, selector, field
{'"Contacts"','*',"FirstName"}

We refer to this format as a “normalized” property path, and it is what the engine works with internally.

Since the normalized property path format is a unwieldy to work with, there is a “concise” format of property paths:

Contacts[*].FirstName

Selectors are bracketed and follow their list, and dots are used as delimiters. Anywhere property path is used in Valence, you can choose whether to use the concise or normalized format. If you choose concise, we’ll normalize it under the hood.

The syntax for a property path is different when reading data and when writing data. That’s because when writing data we also want to include additional instructions for how to handle intermediary layers and how exactly we want to manipulate the destination nodes.

Using Property Path To Read Data

When reading data, field elements are the same as writing data but list selectors differ.

Operator Label Description
* Get All Reads from every possible node in this list
<number> (, <number>) Index Read from each specified index (indexes start at zero)

As you can see, reading is pretty simple. Either you grab all the list items or you can specify certain ones you’re interested in.

Using Property Path To Write Data

When writing data, field elements are the same as reading data but list selectors differ.

Operator Label Description Restrictions
* Copy For Each Each existing item in the target list will receive its own copy of the data value from the source side. Cannot be used as final path element
Distribute When you have a source list and want to give each existing target item one thing from the source list (the opposite of ‘Copy For Each’). Cannot be used as final path element
: Line Up Preserve the source item list position when writing over to the target; this is the one you’ll use the most often.  
+ Add To Add values to what is already in the target list (initializing if empty).  
<number> (, <number>) Index Write to each specified index (indexes start at zero).