# if

## Definition

In a config modifier schema, use `if` to define a conditional state to run a given action or not.

> **Exclusive keywords**
>
> If `properties`, `if`, `concat`,  `switch`, `pipe`, `merge`, `prefer`, or `items` are present at the same nesting level, only the first keyword listed will run. We recommend not listing these keywords together at the same nesting level. 

A conditional allows you to determine how to construct an output value by conditionally executing different keywords, based on the evaluation of a set of values. 

You can use one of these sub-keywords to construct a conditional statement:

- `operator`
- `terms`
- `then`
- `else`

## Order of execution

This keyword executes in the following order:  

1. `omit`
2. `constant`
3. `references`
4. `use`
5. `get`
6. Mutually exclusive keywords at this level:
   - `properties` 
   - **`if`** 
   - `concat` 
   - `switch` 
   - `pipe` 
   - `merge` 
   - `prefer` 
   - `items`
7. `default`
8. `plugin`

## Sub-keywords

### operator

Determines what action to take based on one of the following operators. The config modifier defines what should happen if a value exists and meets the criteria of any of these operators.

> **Definition of existence**
>
> We define <u>existence</u> of a value based on some rules. Specifically, these evaluations are defined as <u>does not exist</u>:
>
> - `undefined`
> - `null`
> - `''`
> - `[]`
> - `NaN`
>
> We specifically treat some Falsy ([learn about Falsy](https://developer.mozilla.org/en-US/docs/Glossary/Falsy)) values as <u>exists</u>:
>
> - `false`
> - `0`
> - `' '` (empty string but padded with a space)

<details>
<summary>equals</summary>

Specifies that all defined `terms` should be equal to each other. 

If the `terms` match, the `then` action occurs. If the values don’t match, the `else` action occurs.

**Example: Equals input**

```json
"identifier": [
   {
     "system": "urn:redox:1a359110-47eb-40f6-924c-1e67079574a4:wshmrn",
     "type": {
       "text": "WSHMRN"
       },
     "value": "050050184"
   },
   ...
]
```

**Example: Equals selector**

```json
$.entry[?(@.resource.resourceType=="Patient")].resource.identifier[*].type.text
```

**Example: Config modifier with equals operator**

```yaml
if:
  operator: equals
  terms:
   - {}
   - constant: WSHMRN
  then:
    constant: MR
  else:
    comment: no match, pass through
```

Based on this example config modifier, the output would be: 

**Example: Equals output**

```json
"identifier": [
   {
     "system": "urn:redox:1a359110-47eb-40f6-924c-1e67079574a4:wshmrn",
     "type": {
       "text": "MR"
       },
      "value": "050050184"
     },
   ...
   }
 ]
```

</details>

<details>
<summary>all</summary>

Specifies that all defined `terms` exist.

If all `terms` are present, the `then` action occurs. If all `terms` aren’t present, the `else` action occurs.

**Example: All input**

```json
"identifier": [
  {
    "system": "urn:redox:1a359110-47eb-40f6-924c-1e67079574a4:wshmrn",
    "type": {
      "text": "WSHMRN"
    },
    "value": "050050184"
  },
  ...
]
```

**Example: All selector**

```json
$.entry[?(@.resource.resourceType=="Patient")].resource.identifier[*]
```

**Example: Config modifier with all operator**

```yaml
if:
  operator: all
  terms:
    - get: type.text
  then:
    if:
      operator: equals
      terms:
        - get: type.text
        - constant: WSHMRN
      then:
        merge:
          - {}
          - properties:
              type:
                properties:
                  text:
                    constant: MR
              system:
                get: system
                plugin:
                  name: text
                  action: replace
                  parameters:
                    newValue: mr
                    searchValue: wshmrn
      else:
        comment: do nothing
  else:
    comment: type.text does not exist, do nothing
```

Based on this example config modifier, the output would be:

**Example: All output**

```json
"identifier": [
  {
    "system": "urn:redox:1a359110-47eb-40f6-924c-1e67079574a4:mr",
    "type": {
      "text": "MR"
    },
    "value": "050050184"
  },
  ...
],
```

</details>

<details>
<summary>some</summary>

Specifies that at least one of the defined `terms` exists.

If at least one of the `terms` is present, the `then` action occurs. If none are present, the `else` action occurs.

Let’s say you have a list of patient contacts that are missing phone number information, which you need for your workflow. You decide to remove contacts that don’t have at least one phone number listed. 

**Example: Some input**

```json
{
 "Patient": {
   ...
   "Contacts": [
        {
          "Address": {
            "City": "Speedy",
            "Country": null,
            "County": null,
            "State": "CA",
            "StreetAddress": "5559 E. Washington St",
            "ZIP": "12345"
          },
          "EmailAddresses": [
          ],
          "FirstName": "Elizabieth",
          "LastName": "Santa",
          "MiddleName": null,
          "PhoneNumber": {
            "Home": "+10000000000",
            "Mobile": "+10000000000",
            "Office": null
          },
          "RelationToPatient": "Other",
          "Roles": [
            "PC"
          ]
        },
        {
          "Address": {
            "City": "Speedy",
            "Country": null,
            "County": null,
            "State": "CA",
            "StreetAddress": "5559 E. Washington St",
            "ZIP": "12345"
          },
          "EmailAddresses": [
          ],
          "FirstName": "Joshua",
          "LastName": "Santa",
          "MiddleName": null,
          "PhoneNumber": {
            "Home": "+15551231234",
            "Mobile": "+15551231234",
            "Office": null
          },
          "RelationToPatient": "Spouse",
          "Roles": [
            "SC"
          ]
        },
        {
          "Address": {
            "City": null,
            "Country": null,
            "County": null,
            "State": null,
            "StreetAddress": null,
            "ZIP": null
          },
          "EmailAddresses": [
          ],
          "FirstName": null,
          "LastName": "Disabled",
          "MiddleName": null,
          "PhoneNumber": {
            "Home": null,
            "Mobile": null,
            "Office": null
          },
          "RelationToPatient": null,
          "Roles": [
            "EMP"
          ]
        }
      ]
   }
}
```

To implement this, you need to rebuild the `Patient.Contacts` array by checking that there’s at least one phone number listed under `PhoneNumber` for each contact. 

**Example: Some selector**

```json
$.Patient.Contacts
```

If at least one phone number is present, you want to keep the contact, otherwise it should be removed. This is an ideal scenario to use the operator of `some` that evaluates a set of terms (phone numbers in this case) where at least one of the values must evaluate to `true`. 

**Example: Config modifier with some operator**

```yaml
items:
  if:
    operator: some
    terms:
      - get: PhoneNumber.Home
      - get: PhoneNumber.Mobile
      - get: PhoneNumber.Office
    then: {}
    else:
      omit: true
```

Based on this example config modifier, the output would be:

**Example: Some output**

```json
{
 "Patient": {
   ...
   "Contacts": [
        {
          "Address": {
            "City": "Speedy",
            "Country": null,
            "County": null,
            "State": "CA",
            "StreetAddress": "5559 E. Washington St",
            "ZIP": "12345"
          },
          "EmailAddresses": [
          ],
          "FirstName": "Katie",
          "LastName": "Santa",
          "MiddleName": null,
          "PhoneNumber": {
            "Home": "+10000000000",
            "Mobile": "+10000000000",
            "Office": null
          },
          "RelationToPatient": "Other",
          "Roles": [
            "PC"
          ]
        },
        {
          "Address": {
            "City": "Speedy",
            "Country": null,
            "County": null,
            "State": "CA",
            "StreetAddress": "5559 E. Washington St",
            "ZIP": "12345"
          },
          "EmailAddresses": [
          ],
          "FirstName": "John",
          "LastName": "Santa",
          "MiddleName": null,
          "PhoneNumber": {
            "Home": "+15551231234",
            "Mobile": "+155531231234",
            "Office": null
          },
          "RelationToPatient": "Spouse",
          "Roles": [
            "SC"
          ]
        }
      ]
   }
}
```

</details>

<details>
<summary>none</summary>

Specifies that none of the defined `terms` exist. 

If none of the `terms` are present, the `then` action occurs. If at least one of the `terms` is present, the `else` action occurs.

**Example: None input**

```json
{
  "Meta": {
    "DataModel": "Results",
    "EventDateTime": "2025-06-10T18:20:25.266744",
    ...
  },
  "Orders": [
    {
      ...
      "Results": [
        {
          "AbnormalFlag": null,
          "Code": "PTEDEVENT",
          "Codeset": "PTEDLRR",
          "CompletionDateTime": null,
          ...
        }
      ],
      "ResultsStatus": "In Process",
      "Status": "In Process",
      "TransactionDateTime": null
    }
  ],
  ...
}
```

**Example: Config modifier with none operator**

```yaml
if: 
	operator: none 
	terms: 
		- {} 
	then: 
		use: initialPayload
		get: Meta.EventDateTime
	else: comment: do nothing
```

Based on this example config modifier, the output would be: 

**Example: None output**

```json
{
  "Meta": {
    "DataModel": "Results",
    "EventDateTime": "2025-06-10T18:20:25.266744",
    ...
  },
  "Orders": [
    {
      ...
      "Results": [
        {
          "AbnormalFlag": null,
          "Code": "PTEDEVENT",
          "Codeset": "PTEDLRR",
          "CompletionDateTime": "2025-06-10T18:20:25.266744",
          ...
        }
      ],
      "ResultsStatus": "In Process",
      "Status": "In Process",
      "TransactionDateTime": null
    }
  ],
  ...
}
```

</details>

<details>
<summary>includes</summary>

Specifies that the first value in the defined `terms` contains the second value.

If the second value is included in the first, the `then` action occurs. If not—or if the first value isn’t an array or a single string—the `else` action occurs.

If a string, value matching is case-sensitive. The second value must be a single primitive value.

##### Array example

**Example: Observations input from initial payload**

```json
"Observations": [
    {
      "AbnormalFlag": null,
      "Code": "93246-7",
      ...
      "Status": "Final",
      "Units": null,
      "Value": "1",
      "ValueType": "Coded Entry"
    },
    {
      "AbnormalFlag": null,
      "Code": "93247-5",
      ...
      "Status": "Final",
      "Units": null,
      "Value": "1",
      "ValueType": "Coded Entry"
    },
    {
      "AbnormalFlag": null,
      "Code": "NF1570400181",
      ...
      "Status": "Final",
      "Units": null,
      "Value": "High Risk",
      "ValueType": "String"
    },
    {
      "AbnormalFlag": null,
      "Code": "93267-3",
      ...
      "Status": "Final",
      "Units": null,
      "Value": "1",
      "ValueType": "Coded Entry"
    },
    {
      "AbnormalFlag": null,
      "Code": "93269-9",
      ...
      "Status": "Final",
      "Units": null,
      "Value": "0",
      "ValueType": "Coded Entry"
    },
    {
      "AbnormalFlag": null,
      "Code": "NF1570400504",
      ...
      "Status": "Final",
      "Units": null,
      "Value": "Putting my notes here",
      "ValueType": "String"
    }
  ]
```

**Example: Observations selector**

```json
$.Observations
```

**Example: Config modifier with concat and include keywords**

```yaml
items:
  if:
   operator: includes
   terms:
      - concat:
        - constant: NF1570400504
        - constant: NF1570400181
        - constant: 93374-7
      - get: Code
   then:
     omit: true
   else:
     comment: pass observation through
```

Based on this example config modifier, the output would be:

**Example: Observations output**

```json
"Observations": [
    {
      "AbnormalFlag": null,
      "Code": "93246-7",
      ...
      "Status": "Final",
      "Units": null,
      "Value": "1",
      "ValueType": "Coded Entry"
    },
    {
      "AbnormalFlag": null,
      "Code": "93247-5",
      ...
      "Status": "Final",
      "Units": null,
      "Value": "1",
      "ValueType": "Coded Entry"
    },
    {
      "AbnormalFlag": null,
      "Code": "93267-3",
      ...
      "Status": "Final",
      "Units": null,
      "Value": "1",
      "ValueType": "Coded Entry"
    },
    {
      "AbnormalFlag": null,
      "Code": "93269-9",
      ...
      "Status": "Final",
      "Units": null,
      "Value": "0",
      "ValueType": "Coded Entry"
    }
  ],
```

##### String example

This example config modifier checks if the string value at `FT1.13.1` includes a substring of a dash (`-`). If the string does include a dash (`-`), then it should split and place the first part of the string in `PV1.3.1` and the second part of the string after the dash (`-`) in `PV1.3.4.1`. If it doesn’t include dash (`-`), then it’ll map from the initial payload’s `Financial[0].Department.Code` (from a `Financials` data model message).

**Example: Includes string input**

```json
{
 ...,
  "FINANCIAL": [
    {
      "FT1": {
        "1": 1,
        "10": "1",
        "11": {
          "1": {
            "1": null
          }
        },
        "13": {
          "1": "SVHCROSCAR-MONTICELO",
          "2": null,
          "3": null
        },
       ...
      }
    }
  ],
  ...,
  "PV1": {
    "19": {
      "1": "2000708548"
    },
    "3": {
      "1": null
    },
    "44": {
      "1": null
    }
  }
}
```

**Example: Includes string selector**

```json
$.PV1.3
```

**Example: Config modifier with includes operator for string**

```yaml
references:
  departmentCode:
    use: processedPayload
    get: FINANCIAL[0].FT1.13.1
if:
  operator: includes
  terms:
    - use: departmentCode
      plugin:
        name: text
        action: lower-case
    - constant: '-'
  then:
    pipe:
      - use: departmentCode
        plugin:
          name: text
          action: split
          parameters:
            separator: '-'
      - properties:
          '1':
            get: '0'
          '4':
            properties:
              '1':
                get: '1'
  else:
    use: initialPayload
    get: Transactions[0].Department.Code
```

Based on this example config modifier, the output would be:

**Example: Output string for includes operator**

```json
{
  ...
  "FINANCIAL": [
    {
      "FT1": {
        "1": 1,
        "10": "1",
        "11": {
          "1": {
            "1": null
          }
        },
        "13": {
          "1": "SVHCROSCAR-MONTICELO",
          "2": null,
          "3": null
        },
       ...
    }
  ],
  "PV1": {
    "19": {
      "1": "2000708548"
    },
    "3": {
      "1": "SVHCROSCAR",
      "4": {
        "1": "MONTICELO"
      }
    },
    "44": {
      "1": null
    }
  }
}
```

</details>

<details>
<summary>greaterThan</summary>

Specifies what action to take when the `value` in the defined `terms` is greater than the specified `constant`. If the value is greater than the `constant`, the `then` action occurs. If not, the `else` action occurs.

> **Define a range**
>
> These operators can be used alone or with any of the others in the list to establish a range: 
>
> - `greaterThan`
> - `greaterThanOrEqual`
> - `lessThan`
> - `lessThanOrEqual`

**Example: Comparison operators input**

```json
{
  ...
  "Orders": [
    {
      ...
      "Results": [
        {
          "AbnormalFlag": "Low",
          ...
          "Value": "JVBERi0",
          "ValueType": "Encapsulated Data"
        },
        {
          "AbnormalFlag": "Low",
          ...
          "Value": "5.4",
          "ValueType": "Value"
        }
      ],
      "ResultsStatus": "Final",
      "Status": "Resulted",
      "TransactionDateTime": "2026-06-03T12:24:36.8253191Z"
    }
  ],
  ...
}
```

**Example: Comparison operators selector**

```json
$.Orders[*].Results[*].AbnormalFlag
```

**Example: Config modifier with comparison operators**

```yaml
comment: < 5 is Normal, < 15 is Mild, <= 30 is Moderate, 30+ is Severe
references:
  value:
    use: '@parent'
    get: Value
    plugin:
      name: convert
      action: string-to-number
prefer:
  - if:
      operator: lessThan
      terms:
        - use: value
        - constant: 5
      then:
        constant: Normal
      else:
        omit: true
  - if:
      operator: lessThan
      terms:
        - use: value
        - constant: 15
      then:
        constant: Mild
      else:
        omit: true
  - if:
      operator: lessThanOrEqual
      terms:
        - use: value
        - constant: 30
      then:
        constant: Moderate
      else:
        omit: true
  - if:
      operator: greaterThan
      terms:
        - use: value
        - constant: 30
      then:
        constant: Severe
      else:
        omit: true
  - comment: passThrough
```

Based on this example config modifier, the output would be:

**Example: Comparison operators output**

```json
{
  ...
  "Orders": [
    {
      ...
      "Results": [
        {
          "AbnormalFlag": "Low",
          ...
          "Value": "JVBERi0xL",
          "ValueType": "Encapsulated Data"
        },
        {
          "AbnormalFlag": "Mild",
          ...
          "Value": "5.4",
          "ValueType": "Value"
        }
      ],
      "ResultsStatus": "Final",
      "Status": "Resulted",
      "TransactionDateTime": "2026-06-03T12:24:36.8253191Z"
    }
  ],
  ...
}
```

##### Example breakdown

Review our notes below for a deeper dive into the config modifier schema we just built. 

###### 1. Using references

**Example breakdown 1: Using references**

```yaml
comment: < 5 is Normal, < 15 is Mild, <= 30 is Moderate, 30+ is Severe
references:
  value:
    use: '@parent'
    get: Value
    plugin:
      name: convert
      action: string-to-number
```

The comparison operator requires the `terms` be a number type, but the `Value` is a string type. So, we need to convert the string to a number. To avoid having to apply the `convert` plugin for each needed comparison, we want to save this as a `reference`.

Since the selector is `$.Orders[*].Results[*].AbnormalFlag`, the input is the value of `AbnormalFlag` of the result of the current order we’re looking at. This makes the parent the current result, which can be retrieved with `use: @parent`. Then we can grab the `Value` from the current result and save it to the `reference` of `value`.

###### 2. Using prefer

**Example breakdown 2: Using prefer**

```yaml
prefer:
```

If the `Value` falls into a certain range, we want to map it to `AbnormalFlag` accordingly. If it doesn’t, we want to compare it against the next range of values.

Intuitively, we usually default to `if`/ `else if` / `else if` /`else` type logic, but `prefer` is a cleaner way to handle this scenario because `prefer` picks the first parameter that exists and assigns it to `AbnormalFlag`.

###### 3. Comparing values

**Example breakdown 3: Comparing values**

```yaml
- if:
      operator: lessThan
      terms:
        - use: value
        - constant: 5
      then:
        constant: Normal
      else:
        omit: true
  - if:
      operator: lessThan
      terms:
        - use: value
        - constant: 15
      then:
        constant: Mild
      else:
        omit: true
  - if:
      operator: lessThanOrEqual
      terms:
        - use: value
        - constant: 30
      then:
        constant: Moderate
      else:
        omit: true
  - if:
      operator: greaterThan
      terms:
        - use: value
        - constant: 30
      then:
        constant: Severe
      else:
        omit: true
  - comment: passThrough
```

The selector `$.Orders[*].Results[*].AbnormalFlag` targets `AbnormalFlag` across every result in every order. In this example, that’s two values:

- Result 1: `AbnormalFlag = "Low"`, `Value = "JVBERi0xL"` (ValueType: Encapsulated Data)
- Result 2: `AbnormalFlag = "Mild"`, `Value = "5.4"` (ValueType: Value)

The `if/then/else` blocks are evaluated _per result_. Each block checks the result’s `Value` against a range (i.e., \< 5). If it doesn’t evaluate to `true`, it maps nothing (`omit: true`). Due to the nature of `prefer`, the multiple blocks together allow for checking the `Value` against a range.

###### **4. Value = 5.4**

The blocks are evaluated in order:

1. Is 5.4 less than 4.9? 
   1. <u>**No**</u> → Nothing maps
2. Is 5.4 less than 14.9? 
   1. <u>**Yes**</u> → maps `Mild`
3. Remaining blocks are still evaluated.
   1.  5.4 doesn’t match them → Nothing maps

`prefer` then scans the outputs in order and takes the _first non-empty result_ (in this case, `Mild`). That becomes the value of `AbnormalFlag`.

If the value doesn't match any condition, all blocks produce no output. `prefer` finds nothing. 

The `comment: passThrough` at the end determines that the `AbnormalFlag` remains unchanged rather than getting cleared.

</details>

<details>
<summary>greaterThanOrEqual</summary>

Specifies what action to take when the `value` in the defined `terms` is greater than or equal to the specified `constant`. If the value is greater than or equal to the `constant`, the `then` action occurs. If not, the `else` action occurs.

> **Define a range**
>
> These operators can be used alone or with any of the others in the list to establish a range: 
>
> - `greaterThan`
> - `greaterThanOrEqual`
> - `lessThan`
> - `lessThanOrEqual`

**Example: Comparison operators input**

```json
{
  ...
  "Orders": [
    {
      ...
      "Results": [
        {
          "AbnormalFlag": "Low",
          ...
          "Value": "JVBERi0",
          "ValueType": "Encapsulated Data"
        },
        {
          "AbnormalFlag": "Low",
          ...
          "Value": "5.4",
          "ValueType": "Value"
        }
      ],
      "ResultsStatus": "Final",
      "Status": "Resulted",
      "TransactionDateTime": "2026-06-03T12:24:36.8253191Z"
    }
  ],
  ...
}
```

**Example: Comparison operators selector**

```json
$.Orders[*].Results[*].AbnormalFlag
```

**Example: Config modifier with comparison operators**

```yaml
comment: < 5 is Normal, < 15 is Mild, <= 30 is Moderate, 30+ is Severe
references:
  value:
    use: '@parent'
    get: Value
    plugin:
      name: convert
      action: string-to-number
prefer:
  - if:
      operator: lessThan
      terms:
        - use: value
        - constant: 5
      then:
        constant: Normal
      else:
        omit: true
  - if:
      operator: lessThan
      terms:
        - use: value
        - constant: 15
      then:
        constant: Mild
      else:
        omit: true
  - if:
      operator: lessThanOrEqual
      terms:
        - use: value
        - constant: 30
      then:
        constant: Moderate
      else:
        omit: true
  - if:
      operator: greaterThan
      terms:
        - use: value
        - constant: 30
      then:
        constant: Severe
      else:
        omit: true
  - comment: passThrough
```

Based on this example config modifier, the output would be:

**Example: Comparison operators output**

```json
{
  ...
  "Orders": [
    {
      ...
      "Results": [
        {
          "AbnormalFlag": "Low",
          ...
          "Value": "JVBERi0xL",
          "ValueType": "Encapsulated Data"
        },
        {
          "AbnormalFlag": "Mild",
          ...
          "Value": "5.4",
          "ValueType": "Value"
        }
      ],
      "ResultsStatus": "Final",
      "Status": "Resulted",
      "TransactionDateTime": "2026-06-03T12:24:36.8253191Z"
    }
  ],
  ...
}
```

##### Example breakdown

Review our notes below for a deeper dive into the config modifier schema we just built. 

###### 1. Using references

**Example breakdown 1: Using references**

```yaml
comment: < 5 is Normal, < 15 is Mild, <= 30 is Moderate, 30+ is Severe
references:
  value:
    use: '@parent'
    get: Value
    plugin:
      name: convert
      action: string-to-number
```

The comparison operator requires the `terms` be a number type, but the `Value` is a string type. So, we need to convert the string to a number. To avoid having to apply the `convert` plugin for each needed comparison, we want to save this as a `reference`.

Since the selector is `$.Orders[*].Results[*].AbnormalFlag`, the input is the value of `AbnormalFlag` of the result of the current order we’re looking at. This makes the parent the current result, which can be retrieved with `use: @parent`. Then we can grab the `Value` from the current result and save it to the `reference` of `value`.

###### 2. Using prefer

**Example breakdown 2: Using prefer**

```yaml
prefer:
```

If the `Value` falls into a certain range, we want to map it to `AbnormalFlag` accordingly. If it doesn’t, we want to compare it against the next range of values.

Intuitively, we usually default to `if`/ `else if` / `else if` /`else` type logic, but `prefer` is a cleaner way to handle this scenario because `prefer` picks the first parameter that exists and assigns it to `AbnormalFlag`.

###### 3. Comparing values

**Example breakdown 3: Comparing values**

```yaml
- if:
      operator: lessThan
      terms:
        - use: value
        - constant: 5
      then:
        constant: Normal
      else:
        omit: true
  - if:
      operator: lessThan
      terms:
        - use: value
        - constant: 15
      then:
        constant: Mild
      else:
        omit: true
  - if:
      operator: lessThanOrEqual
      terms:
        - use: value
        - constant: 30
      then:
        constant: Moderate
      else:
        omit: true
  - if:
      operator: greaterThan
      terms:
        - use: value
        - constant: 30
      then:
        constant: Severe
      else:
        omit: true
  - comment: passThrough
```

The selector `$.Orders[*].Results[*].AbnormalFlag` targets `AbnormalFlag` across every result in every order. In this example, that’s two values:

- Result 1: `AbnormalFlag = "Low"`, `Value = "JVBERi0xL"` (ValueType: Encapsulated Data)
- Result 2: `AbnormalFlag = "Mild"`, `Value = "5.4"` (ValueType: Value)

The `if/then/else` blocks are evaluated _per result_. Each block checks the result’s `Value` against a range (i.e., \< 5). If it doesn’t evaluate to `true`, it maps nothing (`omit: true`). Due to the nature of `prefer`, the multiple blocks together allow for checking the `Value` against a range.

###### **4. Value = 5.4**

The blocks are evaluated in order:

- Is 5.4 less than 4.9? 
  1. <u>**No**</u> → Nothing maps
- Is 5.4 less than 14.9? 
  1. <u>**Yes**</u> → maps `Mild`
- Remaining blocks are still evaluated.
  1.  5.4 doesn’t match them → Nothing maps

`prefer` then scans the outputs in order and takes the _first non-empty result_ (in this case, `Mild`). That becomes the value of `AbnormalFlag`.

If the value doesn't match any condition, all blocks produce no output. `prefer` finds nothing. 

The `comment: passThrough` at the end determines that the `AbnormalFlag` remains unchanged rather than getting cleared.

</details>

<details>
<summary>lessThan</summary>

Specifies what action to take when the `value` in the defined `terms` is less than the specified `constant`. If the value is less than the `constant`, the `then` action occurs. If not, the `else` action occurs.

This is one of the comparison operators, which compares values to a defined range. These operators can be used alone or with any of the others in the list to establish the range: 

> **Define a range**
>
> These operators can be used alone or with any of the others in the list to establish a range: 
>
> - `greaterThan`
> - `greaterThanOrEqual`
> - `lessThan`
> - `lessThanOrEqual`

**Example: Comparison operators input**

```json
{
  ...
  "Orders": [
    {
      ...
      "Results": [
        {
          "AbnormalFlag": "Low",
          ...
          "Value": "JVBERi0",
          "ValueType": "Encapsulated Data"
        },
        {
          "AbnormalFlag": "Low",
          ...
          "Value": "5.4",
          "ValueType": "Value"
        }
      ],
      "ResultsStatus": "Final",
      "Status": "Resulted",
      "TransactionDateTime": "2026-06-03T12:24:36.8253191Z"
    }
  ],
  ...
}
```

**Example: Comparison operators selector**

```json
$.Orders[*].Results[*].AbnormalFlag
```

**Example: Config modifier with comparison operators**

```yaml
comment: < 5 is Normal, < 15 is Mild, <= 30 is Moderate, 30+ is Severe
references:
  value:
    use: '@parent'
    get: Value
    plugin:
      name: convert
      action: string-to-number
prefer:
  - if:
      operator: lessThan
      terms:
        - use: value
        - constant: 5
      then:
        constant: Normal
      else:
        omit: true
  - if:
      operator: lessThan
      terms:
        - use: value
        - constant: 15
      then:
        constant: Mild
      else:
        omit: true
  - if:
      operator: lessThanOrEqual
      terms:
        - use: value
        - constant: 30
      then:
        constant: Moderate
      else:
        omit: true
  - if:
      operator: greaterThan
      terms:
        - use: value
        - constant: 30
      then:
        constant: Severe
      else:
        omit: true
  - comment: passThrough
```

Based on this example config modifier, the output would be:

**Example: Comparison operators output**

```json
{
  ...
  "Orders": [
    {
      ...
      "Results": [
        {
          "AbnormalFlag": "Low",
          ...
          "Value": "JVBERi0xL",
          "ValueType": "Encapsulated Data"
        },
        {
          "AbnormalFlag": "Mild",
          ...
          "Value": "5.4",
          "ValueType": "Value"
        }
      ],
      "ResultsStatus": "Final",
      "Status": "Resulted",
      "TransactionDateTime": "2026-06-03T12:24:36.8253191Z"
    }
  ],
  ...
}
```

##### Example breakdown

Review our notes below for a deeper dive into the config modifier schema we just built. 

###### 1. Using references

**Example breakdown 1: Using references**

```yaml
comment: < 5 is Normal, < 15 is Mild, <= 30 is Moderate, 30+ is Severe
references:
  value:
    use: '@parent'
    get: Value
    plugin:
      name: convert
      action: string-to-number
```

The comparison operator requires the `terms` be a number type, but the `Value` is a string type. So, we need to convert the string to a number. To avoid having to apply the `convert` plugin for each needed comparison, we want to save this as a `reference`.

Since the selector is `$.Orders[*].Results[*].AbnormalFlag`, the input is the value of `AbnormalFlag` of the result of the current order we’re looking at. This makes the parent the current result, which can be retrieved with `use: @parent`. Then we can grab the `Value` from the current result and save it to the `reference` of `value`.

###### 2. Using prefer

**Example breakdown 2: Using prefer**

```yaml
prefer:
```

If the `Value` falls into a certain range, we want to map it to `AbnormalFlag` accordingly. If it doesn’t, we want to compare it against the next range of values.

Intuitively, we usually default to `if`/ `else if` / `else if` /`else` type logic, but `prefer` is a cleaner way to handle this scenario because `prefer` picks the first parameter that exists and assigns it to `AbnormalFlag`.

###### 3. Comparing values

**Example breakdown 3: Comparing values**

```yaml
- if:
      operator: lessThan
      terms:
        - use: value
        - constant: 5
      then:
        constant: Normal
      else:
        omit: true
  - if:
      operator: lessThan
      terms:
        - use: value
        - constant: 15
      then:
        constant: Mild
      else:
        omit: true
  - if:
      operator: lessThanOrEqual
      terms:
        - use: value
        - constant: 30
      then:
        constant: Moderate
      else:
        omit: true
  - if:
      operator: greaterThan
      terms:
        - use: value
        - constant: 30
      then:
        constant: Severe
      else:
        omit: true
  - comment: passThrough
```

The selector `$.Orders[*].Results[*].AbnormalFlag` targets `AbnormalFlag` across every result in every order. In this example, that’s two values:

- Result 1: `AbnormalFlag = "Low"`, `Value = "JVBERi0xL"` (ValueType: Encapsulated Data)
- Result 2: `AbnormalFlag = "Mild"`, `Value = "5.4"` (ValueType: Value)

The `if/then/else` blocks are evaluated _per result_. Each block checks the result’s `Value` against a range (i.e., \< 5). If it doesn’t evaluate to `true`, it maps nothing (`omit: true`). Due to the nature of `prefer`, the multiple blocks together allow for checking the `Value` against a range.

###### **4. Value = 5.4**

The blocks are evaluated in order:

- Is 5.4 less than 4.9? 
  1. <u>**No**</u> → Nothing maps
- Is 5.4 less than 14.9? 
  1. <u>**Yes**</u> → maps `Mild`
- Remaining blocks are still evaluated.
  1.  5.4 doesn’t match them → Nothing maps

`prefer` then scans the outputs in order and takes the _first non-empty result_ (in this case, `Mild`). That becomes the value of `AbnormalFlag`.

If the value doesn't match any condition, all blocks produce no output. `prefer` finds nothing. 

The `comment: passThrough` at the end determines that the `AbnormalFlag` remains unchanged rather than getting cleared.

</details>

<details>
<summary>lessThanOrEqual</summary>

Specifies what action to take when the `value` in the defined `terms` is less than or equal to the specified `constant`. If the value is less than or equal to the `constant`, the `then` action occurs. If not, the `else` action occurs.

> **Define a range**
>
> These operators can be used alone or with any of the others in the list to establish a range: 
>
> - `greaterThan`
> - `greaterThanOrEqual`
> - `lessThan`
> - `lessThanOrEqual`

**Example: Comparison operators input**

```json
{
  ...
  "Orders": [
    {
      ...
      "Results": [
        {
          "AbnormalFlag": "Low",
          ...
          "Value": "JVBERi0",
          "ValueType": "Encapsulated Data"
        },
        {
          "AbnormalFlag": "Low",
          ...
          "Value": "5.4",
          "ValueType": "Value"
        }
      ],
      "ResultsStatus": "Final",
      "Status": "Resulted",
      "TransactionDateTime": "2026-06-03T12:24:36.8253191Z"
    }
  ],
  ...
}
```

**Example: Comparison operators selector**

```json
$.Orders[*].Results[*].AbnormalFlag
```

**Example: Config modifier with comparison operators**

```yaml
comment: < 5 is Normal, < 15 is Mild, <= 30 is Moderate, 30+ is Severe
references:
  value:
    use: '@parent'
    get: Value
    plugin:
      name: convert
      action: string-to-number
prefer:
  - if:
      operator: lessThan
      terms:
        - use: value
        - constant: 5
      then:
        constant: Normal
      else:
        omit: true
  - if:
      operator: lessThan
      terms:
        - use: value
        - constant: 15
      then:
        constant: Mild
      else:
        omit: true
  - if:
      operator: lessThanOrEqual
      terms:
        - use: value
        - constant: 30
      then:
        constant: Moderate
      else:
        omit: true
  - if:
      operator: greaterThan
      terms:
        - use: value
        - constant: 30
      then:
        constant: Severe
      else:
        omit: true
  - comment: passThrough
```

Based on this example config modifier, the output would be:

**Example: Comparison operators output**

```json
{
  ...
  "Orders": [
    {
      ...
      "Results": [
        {
          "AbnormalFlag": "Low",
          ...
          "Value": "JVBERi0xL",
          "ValueType": "Encapsulated Data"
        },
        {
          "AbnormalFlag": "Mild",
          ...
          "Value": "5.4",
          "ValueType": "Value"
        }
      ],
      "ResultsStatus": "Final",
      "Status": "Resulted",
      "TransactionDateTime": "2026-06-03T12:24:36.8253191Z"
    }
  ],
  ...
}
```

##### Example breakdown

Review our notes below for a deeper dive into the config modifier schema we just built. 

###### 1. Using references

**Example breakdown 1: Using references**

```yaml
comment: < 5 is Normal, < 15 is Mild, <= 30 is Moderate, 30+ is Severe
references:
  value:
    use: '@parent'
    get: Value
    plugin:
      name: convert
      action: string-to-number
```

The comparison operator requires the `terms` be a number type, but the `Value` is a string type. So, we need to convert the string to a number. To avoid having to apply the `convert` plugin for each needed comparison, we want to save this as a `reference`.

Since the selector is `$.Orders[*].Results[*].AbnormalFlag`, the input is the value of `AbnormalFlag` of the result of the current order we’re looking at. This makes the parent the current result, which can be retrieved with `use: @parent`. Then we can grab the `Value` from the current result and save it to the `reference` of `value`.

###### 2. Using prefer

**Example breakdown 2: Using prefer**

```yaml
prefer:
```

If the `Value` falls into a certain range, we want to map it to `AbnormalFlag` accordingly. If it doesn’t, we want to compare it against the next range of values.

Intuitively, we usually default to `if`/ `else if` / `else if` /`else` type logic, but `prefer` is a cleaner way to handle this scenario because `prefer` picks the first parameter that exists and assigns it to `AbnormalFlag`.

###### 3. Comparing values

**Example breakdown 3: Comparing values**

```yaml
- if:
      operator: lessThan
      terms:
        - use: value
        - constant: 5
      then:
        constant: Normal
      else:
        omit: true
  - if:
      operator: lessThan
      terms:
        - use: value
        - constant: 15
      then:
        constant: Mild
      else:
        omit: true
  - if:
      operator: lessThanOrEqual
      terms:
        - use: value
        - constant: 30
      then:
        constant: Moderate
      else:
        omit: true
  - if:
      operator: greaterThan
      terms:
        - use: value
        - constant: 30
      then:
        constant: Severe
      else:
        omit: true
  - comment: passThrough
```

The selector `$.Orders[*].Results[*].AbnormalFlag` targets `AbnormalFlag` across every result in every order. In this example, that’s two values:

- Result 1: `AbnormalFlag = "Low"`, `Value = "JVBERi0xL"` (ValueType: Encapsulated Data)
- Result 2: `AbnormalFlag = "Mild"`, `Value = "5.4"` (ValueType: Value)

The `if/then/else` blocks are evaluated _per result_. Each block checks the result’s `Value` against a range (i.e., \< 5). If it doesn’t evaluate to `true`, it maps nothing (`omit: true`). Due to the nature of `prefer`, the multiple blocks together allow for checking the `Value` against a range.

###### **4. Value = 5.4**

The blocks are evaluated in order:

- Is 5.4 less than 4.9? 
  1. <u>**No**</u> → Nothing maps
- Is 5.4 less than 14.9? 
  1. <u>**Yes**</u> → maps `Mild`
- Remaining blocks are still evaluated.
  1.  5.4 doesn’t match them → Nothing maps

`prefer` then scans the outputs in order and takes the _first non-empty result_ (in this case, `Mild`). That becomes the value of `AbnormalFlag`.

If the value doesn't match any condition, all blocks produce no output. `prefer` finds nothing. 

The `comment: passThrough` at the end determines that the `AbnormalFlag` remains unchanged rather than getting cleared.

</details>

### terms

Defines a sequential array of keywords to execute on. All `terms` are evaluated in sequence, then the related operator performs the appropriate action. You can review the requirements for `terms` based on the operator used. 

> **Refer to a selector**
>
> Within the context of a `terms` keyword statement, you can use `{}` to retrieve a value at the already defined selector instead of repeating the same path. [Learn about referring to a selector](https://docs.redoxengine.com/permalink/1EFEDDZG8zyMgYVFlG3eoj/#refer-to-a-defined-selector).

### then / else

These keywords are used in conjunction with each other to define which action should happen when: 

- Execute the `then` action when the `operator` resolves to a `true` state. 
- Execute the `else` action when the `operator` resolves to a `false` state.

#### Example

For example, you could define which fields to use to build an object.

**Example: Then / else input from initial payload**

```json
{
  "Orders": [
    {
      "ApplicationOrderID": "844",
      "ClinicalInfo": [],
      "CollectionDateTime": "2025-05-29T14:59:00.000Z",
      "Comments": null,
      "Diagnoses": [
        {
          "Code": "Z13.71",
          "Codeset": "ICD-10",
          "DocumentedDateTime": null,
          "Name": "Encounter for nonprocreative screening for genetic disease carrier status",
          "Type": "Unknown"
        }
      ],
      ...
      "Procedure": {
        "Code": "523",
        "Codeset": "GDXEAP",
        "Description": "GDX NEURO-NDD"
      },
      ...
      "Status": "Update",
      "TransactionDateTime": "2025-05-29T14:59:25.000Z"
    }
  ],
}
```

**Example: Then / else selector**

```json
$.Orders[*].Procedure.Code
```

**Example: Config modifier with then / else keywords**

```yaml
if:
  operator: equals
  terms:
    - {}
    - constant: '523'
  then:
    constant: '691'
  else:
    comment: pass original value
```

During processing, the request checks if the procedure code equals 523 in the initial payload. If so, the `then` action executes, meaning that the procedure code is set to 691. If the procedure code doesn’t equal 523, the `else` action executes, meaning that the original procedure code is passed.

**Example: Then / else output**

```json
"Orders": [
    {
      "ApplicationOrderID": "844",
      "ClinicalInfo": [],
      "CollectionDateTime": "2025-05-29T14:59:00.000Z",
      "Comments": null,
      "Diagnoses": [
        {
          "Code": "Z13.71",
          "Codeset": "ICD-10",
          "DocumentedDateTime": null,
          "Name": "Encounter for nonprocreative screening for genetic disease carrier status",
          "Type": "Unknown"
        }
      ],
      ...
      "Procedure": {
        "Code": "691",
        "Codeset": "GDXEAP",
        "Description": "GDX NEURO-NDD"
      },
      ...
      "Status": "Update",
      "TransactionDateTime": "2025-05-29T14:59:25.000Z"
    }
  ],
```
