Object Functions and Properties

Overview

Object methods provide powerful ways to inspect, transform, and manipulate objects in expressions. These methods work with all object types and enable sophisticated data transformations without requiring additional Snaps.

Object Literals

Description:

Object literals allow you to construct an object with a set of properties. They function similar to JavaScript object literals.

Special Variables:

Within object literals, the following variables are available:

  • this - Reference to the current object (access previously defined properties)
  • __parent__ - Reference to the parent object in nested literals
  • __root__ - Reference to the top-level object in deeply nested literals

Syntax:

{
    property-name1 : value1,
    property-name2 : value2,
    ...
    property-nameN : valueN
}

Property names can be computed dynamically using an expression in square brackets:

[expression] : value

Example:

{
    "msg": "Hello, World!",
    /* Unlike JSON, property names do not need to be quoted */
    num: 123,
    /* Property names can be computed using an expression */
    [2 * 2]: "four",
    /* Other fields in this object can be referenced using 'this' */
    ref: this.num + 7  /* sets 'ref' equal to 130 (123 + 7) */
}

Inspection Methods

entries()

Returns an array of [key, value] pairs for the object's own enumerable properties.

$user.entries()
// Input: {name: "John", age: 30}
// Returns: [["name", "John"], ["age", 30]]

keys()

Returns an array of strings representing all enumerable property names.

$user.keys()
// Input: {name: "John", age: 30}
// Returns: ["name", "age"]

values()

Returns an array containing the object's own enumerable property values.

$user.values()
// Input: {name: "John", age: 30}
// Returns: ["John", 30]

isEmpty()

Returns true if the object has no properties.

{}.isEmpty()           // Returns: true
{foo: 1}.isEmpty()     // Returns: false
Note: This function is not supported in Spark pipelines.

Property Testing Methods

hasOwnProperty()

Returns a boolean indicating whether the object has the specified property.

$.hasOwnProperty("route")  // Returns: true if "route" property exists

// Use in conditional expression
$.hasOwnProperty('query') ? $query : 'not present in input'
Important: This method treats the argument as a JSONPath and returns false if the property exists but the value is null. For JSONPath queries or when null values are possible, use hasPath() instead.

hasPath()

Returns a boolean indicating whether the object has the specified property (path) with a non-null value. Recommended for working with JSONPath.

$.hasPath("custom.route")  // Returns: true if path exists with non-null value

// Nested path validation
$.hasPath("Editor.EditorName")  // Returns: true if nested path exists
Tip: Instead of chaining multiple hasOwnProperty calls to validate each node of a JSONPath, use hasPath() once with the complete path.

Property Access Methods

get()

Get the value of a property or a default value if the property does not exist.

$.get("Id")           // Returns: value or null
$.get("Id", 123)      // Returns: value or 123 (default)
Note: This function is not supported in Spark pipelines.

getFirst()

Returns the property value, or if it's a populated list, returns the first element. Otherwise returns the default value or null.

$.getFirst("test")           // String "abc123" → "abc123"
$.getFirst("test")           // Array [5, 10, 15, 20] → 5
$.getFirst("missing", "N/A") // Returns: "N/A"

Transformation Methods

extend()

Returns a new object with the properties of the current one merged with the properties of objects passed in.

$.extend({newField1: 'foo'}, {newField2: 'bar'})
// Input: {}
// Returns: {newField1: "foo", newField2: "bar"}

// Convert array of objects to single object
{}.extend(...$myArray)
Note: When using in a Mapper, ensure the input stream is not empty. For empty documents, use {} instead of $.

merge()

Performs a deep merge of this object with those passed in. Objects and arrays are recursively merged.

$.merge({child: {age: 32}})
// Input: {id: 12345, child: {name: "John Doe"}}
// Returns: {id: 12345, child: {name: "John Doe", age: 32}}

Filtering and Mapping Methods

filter()

Creates a new object retaining only properties that match the callback condition.

$.filter((value, key) => key.startsWith("new"))
// Input: {key1: "abc", key2: "xyz", newField1: "foo", newField2: "bar"}
// Returns: {newField1: "foo", newField2: "bar"}

mapKeys()

Transforms property names using a callback function.

$.mapKeys((value, key) => "new" + key)
// Input: {Field1: "foo", Field2: "bar"}
// Returns: {newField1: "foo", newField2: "bar"}

mapValues()

Transforms property values using a callback function.

$.mapValues((value, key) => key == "newField1" ? "foo" : "bar")
// Input: {newField1: "abc", newField2: "xyz"}
// Returns: {newField1: "foo", newField2: "bar"}

Common Patterns

Check Property Existence:

// Simple property
$.hasOwnProperty('userId')

// Nested path
$.hasPath('user.profile.email')

Get with Default Value:

$.get('status', 'pending')      // Returns 'pending' if status is missing
$.getFirst('items', [])         // Returns [] if items is missing

Merge Configurations:

// Merge default config with user config
$defaultConfig.merge($userConfig)

Transform Object Keys:

// Convert keys to uppercase
$.mapKeys((v, k) => k.toUpperCase())

// Add prefix to all keys
$.mapKeys((v, k) => "data_" + k)

Filter Object Properties:

// Keep only non-null values
$.filter((v, k) => v != null)

// Keep only numeric values
$.filter((v, k) => typeof v == "number")

Convert Array to Object:

// Array of objects with unique keys
{}.extend(...$arrayOfObjects)

Extract Keys and Values:

// Get all keys as array
$object.keys()

// Get all values as array
$object.values()

// Get key-value pairs
$object.entries()

Best Practices

  • Null Safety: Use hasPath() instead of hasOwnProperty() when dealing with nested paths or potential null values.
  • Default Values: Use get() with a default value instead of hasOwnProperty() + conditional logic for cleaner code.
  • Immutability: Methods like extend() and merge() return new objects rather than modifying the original.
  • Deep Merge: Use merge() for nested objects; extend() only merges top-level properties.
  • Callback Functions: Use arrow functions in filter(), mapKeys(), and mapValues() for concise transformations.
  • Spark Compatibility: Be aware that get() and isEmpty() are not supported in Spark pipelines.
  • Array Conversion: When converting arrays to objects with extend(), ensure array elements have unique keys.

Method Comparison

Method Purpose Returns
keys() Get property names Array of strings
values() Get property values Array of values
entries() Get [key, value] pairs Array of arrays
hasOwnProperty() Check property exists Boolean
hasPath() Check path exists (non-null) Boolean
get() Get value with default Value or default
extend() Shallow merge New object
merge() Deep merge New object
filter() Keep matching properties New filtered object
mapKeys() Transform property names New object with new keys
mapValues() Transform property values New object with new values