Skip to content

Fuuz Bindings $predicateFilter

Fuuz Wiki Import edited this page Jun 7, 2026 · 1 revision

Fuuz Bindings: $predicateFilter

Article Type: How-To Audience: Developers, App Admins Module: How To

Executive Summary

Every model in the Fuuz GraphQL API has a generic WhereInput type used to filter queries against that model. These WhereInput types assign a PredicateInput type to each field on the model. If you have made a query against a Fuuz GraphQL API, you have likely used a WhereInput to filter the results. These predicates provide a quick and easy way to define filters through a Fuuz GraphQL API, making them a natural fit for the internal workings of screens and Data Flows.

Example query:

# query for CalendarEvents...
query GetEvents ($where: CalendarEventWhereInput) {
  calendarEvent(where: $where) {
    id
    timeZone
    calendarId
  }
}

Variables — where the CalendarEvent's timeZone is 'America/Detroit':

{
  "where": {
    "timeZone": { "_eq": "America/Detroit" }
  }
}

…or with Calendar ID "myCalendar" and priority greater than 100:

{
  "where": {
    "calendarId": { "_eq": "myCalendar" },
    "priority": { "_gt": 100 }
  }
}

Predicates

A predicate can be thought of as a "test" that data must pass in order to be accepted by the filter. If you're using this binding, you should be familiar with this concept from JSONata's $filter function. The main difference between $filter and $predicateFilter is one of representation.

$filter

  • A predicate is represented as a function.
  • An element is accepted if the predicate function returns true when applied to it.
  • Even relatively simple predicates need to be expressed in terms of functions:
$filter(
  $data,
  function($element) {
    $element.code = "A" and $element.active = true
  }
)

$predicateFilter

  • A predicate is expressed as an object of predicate inputs (described below).
  • An element is accepted if it satisfies all of the inputs.
  • Predicates look more like the data they are being used to filter:
$predicateFilter(
  $data,
  {
    "code": { "_eq": "A" },
    "active": { "_eq": true }
  }
)

Note: There are subtle differences between these two example snippets! For example, $predicateFilter uses case-insensitive comparison for strings by default.

Predicate Inputs

Universal Predicate Inputs

These predicate inputs are available for use against fields of any type.

Equality Comparison (_eq)

An equality comparison. Matches when the field value equals the provided input value.

Note: String equality is case-insensitive by default (see caseSensitiveComparison).

Payload

[
  { "id": 1, "label": "One" },
  { "id": 2, "label": "Two" },
  { "id": 3, "label": "Three" },
  { "id": 4, "label": "Four" }
]

Transform

$predicateFilter(
  $,
  { "id": { "_eq": 1 } }
)

Result

[
  { "id": 1, "label": "One" }
]

Is-Null (_isNull)

A null-checking comparison.

  • An input value of true matches where the field value is null or undefined.
  • Any other input value matches where the field value is not null.

Payload

[
  { "id": 1, "userId": "example" },
  { "id": 2, "userId": null },
  { "id": 3, "userId": "test" },
  { "id": 4 }
]

Transform

$predicateFilter(
  $,
  { "userId": { "_isNull": true } }
)

Result

[
  { "id": 2, "userId": null },
  { "id": 4 }
]

List Membership (_in)

Matches when the field value is contained in the list provided by the input value. (Membership is tested using the same rules as _eq.)

Payload

[
  { "id": "myCalendarEvent1", "calendarId": "myCalendar", "eventJson": {} },
  { "id": "otherCalendarEvent1", "calendarId": "otherCalendar", "eventJson": {} },
  { "id": "testCalendarEvent", "calendarId": "testCalendar", "eventJson": {} },
  { "id": "myCalendarEvent2", "calendarId": "myCalendar", "eventJson": {} },
  { "id": "otherCalendarEvent2", "calendarId": "otherCalendar", "eventJson": {} }
]

Transform

$predicateFilter(
  $,
  { "calendarId": { "_in": ["myCalendar", "testCalendar"] } }
)

Result

[
  { "id": "myCalendarEvent1", "calendarId": "myCalendar", "eventJson": {} },
  { "id": "testCalendarEvent", "calendarId": "testCalendar", "eventJson": {} },
  { "id": "myCalendarEvent2", "calendarId": "myCalendar", "eventJson": {} }
]

Comparators (_gt/_lt/_gte/_lte)

These predicate inputs compare the field value to the input value using their respective comparisons.

Input Comparison
_gt (strictly) greater than
_lt (strictly) less than
_gte greater than or equal
_lte less than or equal

Note: String comparison is case-insensitive by default (see caseSensitiveComparison).

Payload

[
  { "id": 1, "label": "One" },
  { "id": 2, "label": "Two" },
  { "id": 3, "label": "Three" },
  { "id": 4, "label": "Four" }
]

Transform

$predicateFilter(
  $,
  { "id": { "_gt": 2 } }
)

Result

[
  { "id": 3, "label": "Three" },
  { "id": 4, "label": "Four" }
]

String-Only Predicate Inputs

These predicate inputs can be used against string fields.

Match Start/End of String (_startsWith/_endsWith)

Performs a starts/ends-with comparison against the field value. Matches if the field value starts/ends with the input value.

Payload

[
  { "id": "myCalendarEvent1", "calendarId": "myCalendar", "eventJson": {} },
  { "id": "otherCalendarEvent1", "calendarId": "otherCalendar", "eventJson": {} },
  { "id": "testCalendarEvent", "calendarId": "testCalendar", "eventJson": {} },
  { "id": "myCalendarEvent2", "calendarId": "myCalendar", "eventJson": {} },
  { "id": "otherCalendarEvent2", "calendarId": "otherCalendar", "eventJson": {} }
]

Transform

$predicateFilter(
  $,
  { "id": { "_endsWith": "Event1" } }
)

Result

[
  { "id": "myCalendarEvent1", "calendarId": "myCalendar", "eventJson": {} },
  { "id": "otherCalendarEvent1", "calendarId": "otherCalendar", "eventJson": {} }
]

Contains Substring (_contains)

Performs a contains comparison against the field value. Matches if the field value contains the input value. The input value can be either a string or a regular expression.

Payload

[
  { "id": "hourly", "label": "Hourly" },
  { "id": "daily", "label": "Daily" },
  { "id": "weekly", "label": "Weekly" },
  { "id": "monthly", "label": "Monthly" },
  { "id": "yearly", "label": "Yearly" }
]

Transform

$predicateFilter(
  $,
  { "label": { "_contains": "rly" } }
)

Result

[
  { "id": "hourly", "label": "Hourly" },
  { "id": "yearly", "label": "Yearly" }
]

Note: Regular expressions have their own case-sensitivity options, so make sure to use the /i flag if you want case-insensitive regular expressions:

Transform

$predicateFilter(
  $,
  { "label": { "_contains": /[aeiou]{2}/i } }
)

Result

[
  { "id": "hourly", "label": "Hourly" },
  { "id": "daily", "label": "Daily" },
  { "id": "weekly", "label": "Weekly" },
  { "id": "yearly", "label": "Yearly" }
]

JSON Predicate Inputs

These predicate inputs can be used on JSON object fields. Unlike the previous examples, JSON predicate input values are provided as objects with two properties:

{
  "path": ["the", "object", "path"],
  "value": "the value to test against the path on the object"
}

If path is empty, the value is tested against the whole object.

Contains Object Comparison (_containsObject)

Performs an object contains comparison. The predicate matches when the JSON field contains the provided JSON path/value entries.

Payload

[
  { "data": { "id": 1, "code": "A", "active": true } },
  { "data": { "id": 2, "code": "B", "active": true } },
  { "data": { "id": 3, "code": "A", "active": false } },
  { "data": { "id": 4, "code": "B", "active": false } },
  { "data": { "id": 5, "code": "A", "active": true } }
]

Transform

$predicateFilter(
  $,
  {
    "data": {
      "_containsObject": {
        "path": [],
        "value": { "code": "A", "active": true }
      }
    }
  }
)

Result

[
  { "data": { "id": 1, "code": "A", "active": true } },
  { "data": { "id": 5, "code": "A", "active": true } }
]

Important: This function always treats strings case-sensitively. Case-insensitive behavior can be achieved using other predicate inputs.

Object Has Key (_has)

Performs an object-has-key comparison. The predicate matches when the JSON field value contains a key matching the input value.

Payload

[
  { "id": 1, "metadata": { "user": { "id": "example" } } },
  { "id": 2, "metadata": { "user": { "id": null } } },
  { "id": 3, "metadata": { "user": { "id": "test" } } },
  { "id": 4 }
]

Transform

$predicateFilter(
  $,
  {
    "metadata": {
      "_has": {
        "path": ["user"],
        "value": "id"
      }
    }
  }
)

Result

[
  { "id": 1, "metadata": { "user": { "id": "example" } } },
  { "id": 2, "metadata": { "user": { "id": null } } },
  { "id": 3, "metadata": { "user": { "id": "test" } } }
]

Using Universal Predicate Inputs on JSON Objects

All prior predicate inputs (_eq/_isNull/_in/etc.) can be used on JSON objects as well. These input values can be provided in two ways.

Nested style — predicate inputs can be nested under any number of property names, implicitly defining the path and value to test the predicate against:

/* Nested Style (implicit `path`/`value`) */
$predicateFilter(
  [
    { "id": 1, "metadata": { "user": { "id": "example" } } },
    { "id": 2, "metadata": { "user": { "id": null } } },
    { "id": 3, "metadata": { "user": { "id": "test" } } },
    { "id": 4 }
  ],
  {
    "metadata": {
      "user": {
        "id": { "_in": ["example", "test"] }
      }
    }
  }
)
/* ->
[
  { "id": 1, "metadata": { "user": { "id": "example" } } },
  { "id": 3, "metadata": { "user": { "id": "test" } } }
]
*/

This approach is intuitive, but can lead to some issues when property names conflict with predicates (see Special Cases below). It also doesn't translate as neatly to query filters, since this structure doesn't match the JSONPredicateInput type used for JSONObject query fields:

{
  "metadata": {
    "user": {
      "id": {
        "_in": ["example", "test"],
        "_lt": "foobar"
      }
    }
  }
}

JSON predicate input style — the path/value object can be provided to any predicate input to run that predicate against the given path on that field value:

/* JSON Predicate Input Style (explicit `path`/`value`) */
$predicateFilter(
  [
    { "id": 1, "metadata": { "user": { "id": "example" } } },
    { "id": 2, "metadata": { "user": { "id": null } } },
    { "id": 3, "metadata": { "user": { "id": "test" } } },
    { "id": 4 }
  ],
  {
    "metadata": {
      "_in": {
        "path": ["user", "id"],
        "value": ["example", "test"]
      }
    }
  }
)
/* ->
[
  { "id": 1, "metadata": { "user": { "id": "example" } } },
  { "id": 3, "metadata": { "user": { "id": "test" } } }
]
*/

This approach is more explicit and better reflects the JSONPredicateInput type used for filtering JSONObject fields. However, it is more awkward to compose complex object filters in this way, requiring the use of an _and predicate to apply multiple filters to the same object:

{
  "_and": [
    {
      "metadata": {
        "_in": {
          "path": ["user", "id"],
          "value": ["example", "test"]
        }
      }
    },
    {
      "metadata": {
        "_lt": {
          "path": ["user", "id"],
          "value": "foobar"
        }
      }
    }
  ]
}

Composite Predicate Inputs

_and/_or/_not

Predicates can be logically combined under _and/_or/_not as follows:

{
  "_and": [ { "...predicate 1": {} }, { "...predicate 2": {} } ],
  "_or": [ { "...predicate 1": {} }, { "...predicate 2": {} } ],
  "_not": { "...predicate": {} }
}
  • _and passes if all predicates in the array pass.
  • _or passes if any predicate in the array passes.
  • _not passes if the given predicate does not pass.

Using the $predicateFilter Binding

Payloads

Predicate filters can be applied to two kinds of payloads: arrays and objects.

Array Payloads

Array payloads are filtered in a similar way as with the $filter function. Each element of the array is tested individually and included in the result only if it satisfies the provided predicate.

$predicateFilter(
  [
    { "id": 1, "code": "A" },
    { "id": 2, "code": "B" },
    { "id": 3, "code": "a" }
  ],
  { "code": { "_eq": "A" } }
)
/* ->
[
  { "id": 1, "code": "A" },
  { "id": 3, "code": "a" }
]
*/

Object Payloads

Object payloads are filtered in a similar way as with the $sift function. Each property of the object is included in the result only if its value satisfies the provided predicate.

$predicateFilter(
  {
    "foo": { "id": 1, "code": "A" },
    "bar": { "id": 2, "code": "B" },
    "baz": { "id": 3, "code": "a" }
  },
  { "code": { "_eq": "A" } }
)
/* ->
{
  "foo": { "id": 1, "code": "A" },
  "baz": { "id": 3, "code": "a" }
}
*/

Special Cases

Dates

Dates in JSON data are typically represented as formatted strings. This is also true for query filters against DateTime fields, since the GraphQL API knows which fields are supposed to be dates and which fields are just plain strings.

This is not true for the $predicateFilter binding; it does not know when a given string is supposed to be a date or not, and therefore will not compare formatted strings correctly as dates.

For example:

/* THIS WILL NOT FILTER DATES PROPERLY */
$predicateFilter(
  [
    { "id": 0, "code": "CODE-A", "time": "2024-01-01T00:00:00.000-04:00" },
    { "id": 1, "code": "CODE-B", "time": "2024-01-01T00:00:00.000-02:00" },
    { "id": 2, "code": "CODE-C", "time": "2024-01-01T00:00:00.000+00:00" },
    { "id": 3, "code": "CODE-D", "time": "2024-01-01T00:00:00.000+02:00" },
    { "id": 4, "code": "CODE-E", "time": "2024-01-01T00:00:00.000+04:00" }
  ],
  { "time": { "_gte": "2024-01-01T00:00:00.000Z" } }
)
/* -> [] (INCORRECT) */

When working with dates, ensure that both your payload and predicate fields are cast to Date objects or moment instances if you want to compare them:

$predicateFilter(
  [
    { "id": 0, "code": "CODE-A", "time": $moment("2024-01-01T00:00:00.000-04:00") },
    { "id": 1, "code": "CODE-B", "time": $moment("2024-01-01T00:00:00.000-02:00") },
    { "id": 2, "code": "CODE-C", "time": $moment("2024-01-01T00:00:00.000+00:00") },
    { "id": 3, "code": "CODE-D", "time": $moment("2024-01-01T00:00:00.000+02:00") },
    { "id": 4, "code": "CODE-E", "time": $moment("2024-01-01T00:00:00.000+04:00") }
  ],
  { "time": { "_gte": $moment("2024-01-01T00:00:00.000Z") } }
)
/* ->
[
  { "id": 0, "code": "CODE-A", "time": "2024-01-01T04:00:00.000Z" },
  { "id": 1, "code": "CODE-B", "time": "2024-01-01T02:00:00.000Z" },
  { "id": 2, "code": "CODE-C", "time": "2024-01-01T00:00:00.000Z" }
]
*/

Keys Conflicting with Predicate Inputs

Sometimes, payload elements will contain properties with names matching predicate input names (like _eq or _in).

For an (admittedly contrived) example, you might want to remove filters from a WhereInput object when they contain "_isNull": true:

/* THIS WILL NOT FILTER PROPERLY */
$predicateFilter(
  /* A hypothetical WhereInput to be used in a query */
  {
    "name": { "_contains": "foo" },
    "metadata": { "_isNull": false },
    "userId": { "_in": ["example", "test"], "_isNull": true }
  },
  /* trying to filter out fields containing `{ "_isNull": true }` */
  { "_not": { "_isNull": { "_eq": true } } }
)

The property name "_isNull" conflicts with the _isNull predicate input, making the filter ambiguous. In these ambiguous cases, the $predicateFilter binding always prefers to interpret it as a predicate instead of an implicit path. To disambiguate, use the explicit path/value style described in the JSON Predicate Inputs section above:

$predicateFilter(
  {
    "name": { "_contains": "foo" },
    "metadata": { "_isNull": false },
    "userId": { "_in": ["example", "test"], "_isNull": true }
  },
  {
    "_not": {
      /* the `path`/`value` style for JSON properties is unambiguous */
      "_eq": {
        "path": ["_isNull"],
        "value": true
      }
    }
  }
)
/* ->
{
  "name": { "_contains": "foo" },
  "metadata": { "_isNull": false }
}
*/

Options

caseSensitiveComparison

(Boolean: defaults to false)

While false (the default), string values will be compared case-insensitively. (Both predicate and payload field values will be converted to lowercase for comparison.) This reflects the behavior of a Fuuz GraphQL API, which matches string fields case-insensitively.

While true, string fields will be kept in their original casing for all comparisons.

$predicateFilter(
  [
    { "id": 1, "code": "A" },
    { "id": 2, "code": "B" },
    { "id": 3, "code": "a" }
  ],
  { "code": { "_gte": "B" } }
)
/* -> [{ "id": 2, "code": "B" }] */

$predicateFilter(
  [
    { "id": 1, "code": "A" },
    { "id": 2, "code": "B" },
    { "id": 3, "code": "a" }
  ],
  { "code": { "_gte": "B" } },
  { "caseSensitiveComparison": true }
)
/* ->
[
  { "id": 2, "code": "B" },
  { "id": 3, "code": "a" }
]
*/

$predicateFilter Examples

Equality Comparison

An equality comparison. Matches when the field value equals the provided input value.

$predicateFilter(
  [
    { "id": 1, "label": "One" },
    { "id": 2, "label": "Two" },
    { "id": 3, "label": "Three" },
    { "id": 4, "label": "Four" }
  ],
  {
    "id": { "_eq": 1 }
  }
)

Result:

[{ "id": 1, "label": "One" }]

Object Contains Comparison

Performs an object contains comparison. The predicate matches when the JSON field contains the provided JSON path/value entries.

$predicateFilter(
  [
    { "data": { "id": 1, "code": "A", "active": true } },
    { "data": { "id": 2, "code": "B", "active": true } },
    { "data": { "id": 3, "code": "A", "active": false } },
    { "data": { "id": 4, "code": "B", "active": false } },
    { "data": { "id": 5, "code": "A", "active": true } }
  ],
  {
    "data": {
      "_containsObject": {
        "path": [],
        "value": { "code": "A", "active": true }
      }
    }
  }
)

Result:

[
  { "data": { "id": 1, "code": "A", "active": true } },
  { "data": { "id": 5, "code": "A", "active": true } }
]

Object Payload Property Filtering

Object payloads are filtered in a similar way as with the $sift function. Each property of the object is included in the result only if its value satisfies the provided predicate.

$predicateFilter(
  {
    "foo": { "id": 1, "code": "A" },
    "bar": { "id": 2, "code": "B" },
    "baz": { "id": 3, "code": "a" }
  },
  { "code": { "_eq": "A" } }
)

Result:

{
  "foo": { "id": 1, "code": "A" },
  "baz": { "id": 3, "code": "a" }
}

See Also


Source: support.fuuz.com

🏠 Home

Getting Started (14)
Training Guides (52)

Applications

Access & Users

Data Models & Schema

Screens

Weather Lookup Series — guided 3-part build

Data Flows & Integrations

Data, Reporting & Monitoring

Enterprise & Organizations

Platform Concepts & Architecture (10)
Screens & Application Design (17)
Data Models & Schema (8)
Data Flows & Scripting (51)

Designing Flows

Data Flow Nodes

JSONata Reference

Scripting

Integrations & Connectors (30)

General & iPaaS

Plex

EDI

IIoT & Edge Gateway (18)

Physical Device Connectors

Edge Data Connectors

Reporting, Documents & Dashboards (8)
Administration & Access Control (27)
Data Management (8)
Accelerators, Templates & Packages (8)
Design Standards (1)
How-To Guides (8)
FAQ & Troubleshooting (1)
Release Notes (117)

2026

2025

2024

2023

2022

2021

2020

Policies & Company (6)

Clone this wiki locally