# Modifier

Modifiers transform data on the fly within a flow. They allow you to apply a [JSONata](#jsonata) or [JavaScript expression](#javascript-expressions) to change the structure or value of an output before passing it to the next function, a database, the frontend, or a subsequent extension (such as another modifier or filter).

Modifiers are part of the function extensions. To add a modifier to your function:

1. Click the `+` icon on the right side of any function output, filter, or existing modifier.
2. Select modifier from the list.
3. A new modifier box will appear where you can write your JavaScript logic.

A modifier uses either JSONata or a JavaScript expression. You can switch between types by right-clicking the modifier and selecting JSONata or Expression and adjust the default inside the [App Builder settings](https://docs.heisenware.com/app-builder/build-backend/broken-reference).

<figure><img src="https://3495989837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FE5Ketpww1s7TauSAJrJ8%2Fuploads%2FFjHIkHwTeVxyf1Fr6Usx%2Fimage.png?alt=media&#x26;token=c419cf80-889b-4f1f-b2ef-a0150965b3ce" alt=""><figcaption></figcaption></figure>

{% hint style="success" %}
**Need help writing modifiers?** Read about how to best [use AI for writing modifiers](#using-ai-for-modifiers) to generate JSONata or JavaScript logic instantly using your favorite chatbot.
{% endhint %}

## **JSONata**

JSONata is a query and transformation language designed for JSON data. It is the preferred method for structural changes, filtering, and simple math. For a complete guide, refer to the [official JSONata documentation](https://docs.jsonata.org/overview.html).

* **Reference**: Use the `$` sign to refer to the value from the preceding output.
* **Implicit arguments**: In Heisenware, JSONata modifiers automatically process the incoming data if the parentheses are left empty. For example, `$uppercase()` is equivalent to `$uppercase($)`.

### JSONata examples

<details>

<summary><strong>Example 1: Path selection and math</strong></summary>

Extracts a specific nested value from a PLC object and performs a calculation.

Data:

```json
{
  "payload": {
    "sensors": {
      "temp_c": 25
    }
  }
}
```

Modifier content:

```
payload.sensors.temp_c * 1.8 + 32
```

Return of the modifier:

```
77
```

<figure><img src="https://3495989837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FE5Ketpww1s7TauSAJrJ8%2Fuploads%2FYih04kJt87YAIb1VRJGB%2Fimage.png?alt=media&#x26;token=75f25384-fcdd-4d01-af58-e744d361f5ef" alt=""><figcaption></figcaption></figure>

</details>

<details>

<summary><strong>Example 2: Wrap a value in an object</strong> </summary>

Takes the incoming value (`$`) and wraps it inside a JSON object with a key named `temp_sensor_1`.

Data:

```json
25.4
```

Modifier content:

```
{ "temp_sensor_1": $ }
```

Return of the modifier:

```json
{ "temp_sensor_1": 25.4 }
```

<figure><img src="https://3495989837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FE5Ketpww1s7TauSAJrJ8%2Fuploads%2FtdwrqxZ0Iuh7652OQqav%2Fimage.png?alt=media&#x26;token=2a830034-cf7c-40f1-bf8a-8d433a3c4d07" alt=""><figcaption></figcaption></figure>

</details>

<details>

<summary><strong>Example 3: Implicit function usage</strong> </summary>

Trims whitespace and converts a raw string to uppercase without explicitly naming the input variable.

Data:

```json
"maintenance_required"
```

Modifier content:

```
$uppercase()
```

Return of the modifier:

```json
"MAINTENANCE_REQUIRED"
```

<figure><img src="https://3495989837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FE5Ketpww1s7TauSAJrJ8%2Fuploads%2FWmDJDoLD0H7CuSbvCbEd%2Fimage.png?alt=media&#x26;token=b3e31824-7933-44b9-a470-84e0abfeffac" alt=""><figcaption></figcaption></figure>

</details>

<details>

<summary><strong>Example 4: Filtering an array</strong> </summary>

Returns only the objects from a list that meet a specific status condition.

Data:

```json
[
  { "id": "A1", "status": "OK" },
  { "id": "B2", "status": "ERROR" }
]
```

Modifier content:

```
$[status="ERROR"]
```

Return of the modifier:

```json
{ "id": "B2", "status": "ERROR" }
```

<figure><img src="https://3495989837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FE5Ketpww1s7TauSAJrJ8%2Fuploads%2F9eVvUxEqAE5TdnXApiU6%2Fimage.png?alt=media&#x26;token=08b1c438-5a86-4835-818f-1d21cecc4469" alt=""><figcaption></figcaption></figure>

</details>

## **JavaScript expressions**

This modifier allows you to use any standard JavaScript expression that evaluates to a new value. Reference the reserved variable `x` to access the preceding data output. For more information, refer to the MDN documentation for [JavaScript Expressions and Operators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_operators).

### JavaScript expression examples

<details>

<summary><strong>Example 1: Conditional status (Ternary)</strong> </summary>

Determines a status string based on a numeric threshold.

Data:

```json
85.5
```

Modifier content:

```javascript
x > 80 ? "Critical" : "Normal"
```

Return of the modifier:

```
"Critical"
```

<figure><img src="https://3495989837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FE5Ketpww1s7TauSAJrJ8%2Fuploads%2F9rK8bblmdnxvJvjg1DEd%2Fimage.png?alt=media&#x26;token=c90dd46d-3c50-4251-b664-62ecb4441b09" alt=""><figcaption></figcaption></figure>

</details>

<details>

<summary><strong>Example 2: Array mapping and enrichment</strong></summary>

Iterates through an array of objects to add a new property or modify existing ones using the `.map()` function.

Data:

```json
[
  { "part": "Bolt", "qty": 10 },
  { "part": "Nut", "qty": 5 }
]
```

Modifier content:

```javascript
x.map(item => ({
  ...item,
  available: item.qty > 0,
  lastChecked: DateTime.now().toISODate()
}))
```

Return of the modifier:

```json
[
  { "part": "Bolt", "qty": 10, "available": true, "lastChecked": "2026-02-12" },
  { "part": "Nut", "qty": 5, "available": true, "lastChecked": "2026-02-12" }
]
```

<figure><img src="https://3495989837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FE5Ketpww1s7TauSAJrJ8%2Fuploads%2Fho4llpGsIZoFuy7vL6Dn%2Fimage.png?alt=media&#x26;token=7b795e37-5222-443d-b4f4-5494a2934bc2" alt=""><figcaption></figcaption></figure>

</details>

<details>

<summary><strong>Example 3: Multi-step logic (IIFE)</strong></summary>

While modifiers only support expressions, you can use the Immediately Invoked Function Expression (IIFE) pattern for more elaborate logic involving temporary variables.

Data:

```json
{ "raw_value": 1024, "multiplier": 0.5 }
```

Modifier content:

```javascript
(() => {
  const base = x.raw_value;
  const factor = x.multiplier;
  const offset = 10;
  return (base * factor) + offset;
})()
```

Return of the modifier:

```json
522
```

<figure><img src="https://3495989837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FE5Ketpww1s7TauSAJrJ8%2Fuploads%2FmxENhFPfcckSV2CfXoKN%2Fimage.png?alt=media&#x26;token=ddba16a7-27cf-47bc-8e54-1f3a723355ba" alt=""><figcaption></figcaption></figure>

</details>

<details>

<summary><strong>Example 4: Removing and adding properties in an array</strong></summary>

Use the spread operator (`...`) to reproduce existing entries while selectively removing or adding properties.

Data:

```json
[ { "a": 1, "b": 1, "c": 1 }, { "a": 2, "b": 2, "c": 2 } ]
```

Modifier content:

```javascript
x.map(y => ({
  ...y,         // Reproduces existing entry
  c: undefined, // Removes property c
  d: 'cool'     // Adds property d
}))
```

Return of the modifier:

```json
[ { "a": 1, "b": 1, "d": "cool" }, { "a": 2, "b": 2, "d": "cool" } ]
```

<figure><img src="https://3495989837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FE5Ketpww1s7TauSAJrJ8%2Fuploads%2FLwOqyEVb7ZZKphoPpi3p%2Fimage.png?alt=media&#x26;token=1d6f57fe-1620-4660-b015-c07f6bd9236f" alt=""><figcaption></figcaption></figure>

</details>

<details>

<summary><strong>Example 5: Processing multiple inputs (using <code>combine</code> function)</strong></summary>

When using the `combine` function, the IIFE pattern allows you to cleanly handle multiple input sources stored in the `x` array.

Data (combined by the combine function):

```json
[
  [ { "name": "User1" } ], // x[0]
  [ { "asset": "CNC" } ]   // x[1]
]
```

Modifier content:

```javascript
(() => {
  const users = x[0]
  const assets = x[1]
  return { 
    assigned_users: users, 
    active_assets: assets 
  }
})()
```

Return of the modifier:

```json
{ 
  "assigned_users": [ { "name": "User1" } ], 
  "active_assets": [ { "asset": "CNC" } ] 
}
```

<figure><img src="https://3495989837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FE5Ketpww1s7TauSAJrJ8%2Fuploads%2Fv2lGQUCia3a820DgMDoj%2Fimage.png?alt=media&#x26;token=5c9c2845-ef72-42ff-9d99-bb7a6fbdc48f" alt=""><figcaption></figcaption></figure>

</details>

<details>

<summary><strong>Example 6: Date calculations (using Luxon)</strong></summary>

Heisenware provides built-in support for the [Luxon](https://moment.github.io/luxon/) library via the `DateTime` , `Duration` and `Interval` object for complex time-series operations.

{% hint style="warning" %}
`Duration` and `Interval` are only available from version v91
{% endhint %}

Here are some common modifier patterns:

#### 1. Calculating Future/Past Dates (Addition & Subtraction)

Data:

```json
[
  { "startDate": "2026-01-01", "days": 5 },
  { "startDate": "2026-01-10", "days": 2 }
]
```

Modifier content:

```javascript
x.map(y => ({
   ...y,
   dueDate: DateTime.fromISO(y.startDate).plus({ days: y.days }).toISODate()
}))
```

Return of the modifier:

```json
[
  { "startDate": "2026-01-01", "days": 5, "dueDate": "2026-01-06" },
  { "startDate": "2026-01-10", "days": 2, "dueDate": "2026-01-12" }
]
```

<figure><img src="https://3495989837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FE5Ketpww1s7TauSAJrJ8%2Fuploads%2FZkmtcdXGA8o4o2Ur4LYa%2Fimage.png?alt=media&#x26;token=0d65f8d3-d681-4ca9-861c-03747cf94710" alt=""><figcaption></figcaption></figure>

#### 2. Calculating Downtime (Time Differences)

Find the exact duration between two timestamps, such as a machine fault start and end time.

Data:

```json
[
  { "machine": "Press A", "faultStart": "2026-03-12T08:00:00Z", "faultEnd": "2026-03-12T10:15:00Z" }
]
```

Modifier content:

```javascript
x.map(y => ({
   ...y,
   downtime: DateTime.fromISO(y.faultEnd)
      .diff(DateTime.fromISO(y.faultStart), ['hours', 'minutes'])
      .toFormat("h 'hrs' m 'mins'")
}))
```

Return of the modifier:

```json
[
  { "machine": "Press A", "faultStart": "2026-03-12T08:00:00Z", "faultEnd": "2026-03-12T10:15:00Z", "downtime": "2 hrs 15 mins" }
]
```

***

#### 3. Formatting Decimal Labor Hours

Convert raw decimal hours from timesheets or logs into standard `HH:mm` timecode using the `Duration` object.

Data:

```json
[
  { "worker": "Alice", "loggedDecimal": 8.75 },
  { "worker": "Bob", "loggedDecimal": 7.1 }
]
```

Modifier content:

```javascript
x.map(y => ({
   ...y,
   standardTime: Duration.fromObject({ hours: y.loggedDecimal }).toFormat("hh:mm")
}))
```

Return of the modifier:

```json
[
  { "worker": "Alice", "loggedDecimal": 8.75, "standardTime": "08:45" },
  { "worker": "Bob", "loggedDecimal": 7.1, "standardTime": "07:06" }
]
```

***

#### 4. Validating Events Against Shifts (Intervals)

Check if a specific event (like a sensor trigger) occurred within a defined time window or shift using the `Interval` object.

Data:

```json
[
  { "eventTime": "2026-03-12T14:30:00Z", "shiftStart": "2026-03-12T06:00:00Z", "shiftEnd": "2026-03-12T18:00:00Z" },
  { "eventTime": "2026-03-12T20:00:00Z", "shiftStart": "2026-03-12T06:00:00Z", "shiftEnd": "2026-03-12T18:00:00Z" }
]
```

Modifier content:

```javascript
x.map(y => ({
   ...y,
   occurredDuringShift: Interval.fromDateTimes(
      DateTime.fromISO(y.shiftStart), 
      DateTime.fromISO(y.shiftEnd)
   ).contains(DateTime.fromISO(y.eventTime))
}))
```

Return of the modifier:

```json
[
  { "eventTime": "2026-03-12T14:30:00Z", "shiftStart": "...", "shiftEnd": "...", "occurredDuringShift": true },
  { "eventTime": "2026-03-12T20:00:00Z", "shiftStart": "...", "shiftEnd": "...", "occurredDuringShift": false }
]
```

***

#### 5. Converting UTC Sensor Data to Local Time

IoT devices typically send data in UTC. Convert this to a readable local format for UI dashboards.

Data:

```json
[
  { "sensorId": "Temp-01", "utcTimestamp": "2026-03-12T07:43:50Z" }
]
```

Modifier content:

```javascript
x.map(y => ({
   ...y,
   localFormatted: DateTime.fromISO(y.utcTimestamp).toLocal().toFormat("dd. MMM yyyy, HH:mm:ss")
}))
```

Return of the modifier:

```json
[
  { "sensorId": "Temp-01", "utcTimestamp": "2026-03-12T07:43:50Z", "localFormatted": "12. Mar 2026, 08:43:50" }
```

</details>

<details>

<summary><strong>Example 7: Round robin (using <code>combine</code> function)</strong></summary>

Sometime you want to extract items of an array in a round-robin fashion. For that you can use a `combine` function in which you link back the modifier's output to the second argument:

<figure><img src="https://3495989837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FE5Ketpww1s7TauSAJrJ8%2Fuploads%2F1AORzt08zbZWnqJrqN72%2Fimage.png?alt=media&#x26;token=3c5ddb75-6cfb-46ea-bc3a-2394d8b1ebda" alt=""><figcaption></figcaption></figure>

Data:

```json
[a, b, c]
```

Modifier content:

```javascript
(() => {
  const [arr, prev] = x
  const last = prev ? prev : arr[0]
  const index = prev ? arr.indexOf(last) : -1
  const next = arr[(index + 1) % arr.length]
  return next
})()
```

Return of the modifier:

```json
a // when triggered first time
b // second time
c // third time
a // fourth time
```

</details>

## Using AI for modifiers

You can use AI chatbots (ChatGPT, Claude, Gemini) to generate or optimize your modifiers. This is particularly helpful for complex data transformations where you need to reshape large JSON objects on the fly within the Heisenware visual programming environment.

To optimize results, copy this article as context for the AI. Use the Copy button at the top of the page or the direct Open in ChatGPT / Open in Claude buttons located in the top navigation bar.

#### Recommended AI prompt

Alternatively to using the full article, copy and paste this prompt into your AI to ensure it understands the Heisenware environment and specific variable references.

```
I am working in Heisenware, a node-based visual programming tool for industrial applications. I need to write a "Modifier" to transform data on the fly between functions. 

Context:
* Heisenware uses modifiers to transform data in real-time as it flows through a node-based system.
* If I use JSONata, the input data is referenced as $.
* In JSONata, functions can use empty parentheses () to automatically process the incoming data.
* If I use JavaScript, the input data is referenced as x.
* For JavaScript, I can use the Luxon library via the DateTime object.
* I need a concise expression that returns the transformed value.

My Task:
[Describe your data transformation here, e.g., "I have an array of PLC sensor objects and I need to extract the 'temp_c' property from each to calculate an average OEE value."]
```
