Beyond basic access to array properties via using the index and last notations there is also the notation option findby. This notations works with all array fields with and Context Query.

The notation findby is designed to find an item in array by a simple match on one of it’s properties and return a property value from that found item. The findby notation is similar to javascript lambda expressions used on arrays. Let’s demonstrate this with an example first using a lambda expression.

const commercialLoanExample = {
    id: "123",
    guarantees: [
        {
            name: "Corporate"
        }
    ]
}

// Example lambda expression to find from the guarantee 
// with name Corporate and return property name 
// from the guaranteeType

const guaranteeName = commercialLoanExample
    .guarantees
    .find(guaranteeType => guaranteeType.name === "Corporate")
    .name;

Now let’s create the equivalent using the findby expression with same example commercial loan object as query.

query: {
    name: "getPropertyFromCommercialLoanAccount",
    args: ["guarantees.findby>name>Corporate.guaranteeType.name"]
},
comparator: "==",
value: "Corporate",
type: "string"

The expression is delineated by the > symbols where the first value to the right of findby represents the variable name identifying the current array item.

guarantees.findby>guaranteeType is equivalent to .guarantees.find(guaranteeType

The second value represents a property on the that current array item.

guaranteeType.name is equivalent to guaranteeType>name

After the third > symbol that represents the value that the property value must equal.

guaranteeType.name === "Corporate" is equivalent to guaranteeType>name>Corporate

If a match exists the . dot notation is referencing the array object properties that will be returned to the comparator.

.find(guaranteeType => guaranteeType.name === "Corporate").name is equivalent to findby>guaranteeType>name>Corporate.guaranteeType.name

It is possible to also use multiple findby notations in a single expression. Following the same approach as the previous example the first part will be done in a lambda style and the second using the query expression.

const commercialLoanExample = {
    id: "123",
    guarantees: [
        {
            id: "456",
            name: "Corporate",
            guaranteeTypes: [
                {
                    name: "Something",
                    property1: {
                        property2: "value"
                    }
                }
            ]
        }
    ]
};

const guaranteeTypeName = commercialLoanExample
    .guarantees
    .filter(guarantee => guarantee.id === "456")
    .map(guarantee => guarantee.guaranteeTypes.find(g => g.property1.property2 === "value"))[0].name

Now the equivalent written as a query expression.

query: {
    name: "getPropertyFromCommercialLoanAccount",
    args: ["guarantees.findby>id>456.guaranteeTypes.findby>property1>property2>value.name"]
},
comparator: "==",
value: "Something",
type: "string"

The result of the rules apply so in the above example when the second findby> is used the array item being referenced is an object from the guaranteeTypes array and not the guarantees.

All fields that can be used with a query with arrays are denoted with []. For example, facilityRatings[loanFacilityRating].id could be queried like:

Example

// getting the id of the first facility Rating
query: {
  name: "getPropertyFromCommercialLoanAccount",
  args: ["facilityRatings.0.id"]
}

// getting the id of the last facility Rating
query: {
  name: "getPropertyFromCommercialLoanAccount",
  args: ["facilityRatings.last.id"]
}

//getting the id of the facility Rating with the name test
query: {
  name: "getPropertyFromCommercialLoanAccount",
  args: ["facilityRatings.findby>loanFacilityRating>name?test.id"]
}