Components

customconditionaldatafetch

A guarded variant of customgenericdatafetch that skips duplicate calls, chains dependent fetches, and conditionally fires only when a fetchCondition is met.

A guarded variant of customgenericdatafetch that skips duplicate calls, chains dependent fetches, and conditionally fires only when a fetchCondition is met.

Read Form Rules before using this component — keys, labels, required fields, expressions, visibility, and validation all follow shared conventions.

When to use

  • Preventing duplicate API calls when a field changes after the first call already executed
  • Chaining dependent fetches so each fires only after the previous one succeeds (check → delete → create patterns)
  • Skipping a fetch entirely when a fetchCondition is not met (e.g. only fetch passport validity when document type is "PASSPORT")
  • Hidden background fetches that need conditional or sequential execution

When NOT to use

Instead of customconditionaldatafetch, use…For…
customgenericdatafetchAny single fetch that does not need conditional skipping or sequential chaining
customgenericguardeddatafetchA visible input that triggers a main fetch only after pre-flight checks all pass
genericbuttonfetchA standalone button trigger with no input field
customotpdatafetchOTP-verified data fetch (send OTP, verify, then fetch)

customconditionaldatafetch is the "guarded" sibling of customgenericdatafetch. If you have neither a fetchCondition nor a chained ON_SUCCESS dependency, use customgenericdatafetch instead — there is no reason to use this variant without those features.

Props

PropTypeRequired?Description
labelstringrequiredInternal identifier — typically set to the field key; never shown to the user.
urlstringrequiredIntegration endpoint path — always "/integration/v1/fetch/sync".
endpointCodestringrequiredIntegration endpoint code for this fetch.
triggerTypestringrequired"FIELD_LISTENER" to fire on field change; "TRIGGER_BUTTON" on button click; "ON_SUCCESS" to chain after another fetch.
useBaseUrlbooleanoptionalPrepend the API gateway base URL; set true for all production endpoints.
debounceTimenumberoptionalMilliseconds to wait after trigger before firing (default 500).
hideFieldbooleanoptionalAlways set to true; this component has no visible UI.
hideFromPreviewbooleanoptionalSet true to exclude this field from the application preview.
requiredbooleanoptionalAlways false.
defaultRequiredbooleanoptionalAlways false.
populatesarrayoptional{ valueKey, targetKey } mappings to write response values into the form model.
payloadKeystringoptionalSingle-key payload shorthand — the value of this model field is sent under this key.
payloadKeyMappingsarrayoptionalMulti-field payload — see shape below.
useMultiplePayloadKeysbooleanoptionalSet true when payloadKeyMappings has more than one entry.
populateRelativeToRootFormbooleanoptionalPopulate fields across sections using root-form paths.
onSuccessOfstringconditionalKey of the fetch that must succeed before this one fires — required when triggerType: "ON_SUCCESS".
fetchConditionobjectoptionalSkip this fetch unless the condition passes — see shape below.
errorMappingobjectoptionalAdvanced API error parsing — see shape below.
showGlobalErrorbooleanoptionalSurface errors in the global form error display.

payloadKeyMappings item shape

KeyTypeDescription
keystringPayload field name sent to the endpoint
isStaticbooleantrue to send a hardcoded value
staticValuestring | arrayValue sent when isStatic: true
sourceFieldstringForm model key whose current value is sent (used when not static)

fetchCondition shape

KeyTypeDescription
fieldstringForm model key to evaluate.
operatorstring"EQ" equals, "NEQ" not equals, "GT" greater than, "LT" less than, "GTE" ≥, "LTE" ≤, "CONTAINS" text or array contains.
valueanyValue to compare the field against.
searchInRootFormbooleantrue to resolve field from the root form model rather than local scope.

errorMapping shape

KeyTypeDescription
detectionTypestring"advanced" for structured error parsing.
useApiMessagebooleanExtract the error text from the API response body.
defaultErrorCodestringValidator key to emit when the API returns an error (e.g. "invalidGenericInput").
errorMessagePathstringDot-path in the response body to the error message (e.g. "responseMessage.message").

Examples

Conditional skip — only fetch when a condition is met

Only fetches passport validity when the selected document type is "PASSPORT".

{
  "key": "CHECK_PASSPORT_VALIDITY",
  "type": "customconditionaldatafetch",
  "props": {
    "label": "CHECK_PASSPORT_VALIDITY",
    "url": "/integration/v1/fetch/sync",
    "useBaseUrl": true,
    "endpointCode": "PASSPORT_CHECK",
    "triggerType": "FIELD_LISTENER",
    "debounceTime": 500,
    "hideField": true,
    "required": false,
    "defaultRequired": false,
    "payloadKey": "passportNumber",
    "fetchCondition": {
      "field": "DOCUMENT_TYPE",
      "operator": "EQ",
      "value": "PASSPORT"
    },
    "populates": [{ "valueKey": "isValid", "targetKey": "PASSPORT_VALID" }]
  },
  "validation": {
    "messages": {
      "invalidInput": "Could not validate passport",
      "invalidGenericInput": "A technical issue occurred. Please try again later."
    }
  }
}

Sequential chain — check, conditionally delete, then create

The entry-point fetch uses FIELD_LISTENER; all chained fetches use ON_SUCCESS and reference the predecessor via onSuccessOf. Each branch uses a fetchCondition to decide whether to fire.

[
  {
    "key": "CHECK_DRAFT",
    "type": "customconditionaldatafetch",
    "props": {
      "label": "CHECK_DRAFT",
      "url": "/integration/v1/fetch/sync",
      "useBaseUrl": true,
      "endpointCode": "RDB_BUSINESS_FETCH_1",
      "triggerType": "FIELD_LISTENER",
      "debounceTime": 500,
      "hideField": true,
      "required": false,
      "defaultRequired": false,
      "payloadKeyMappings": [
        { "key": "surname", "sourceField": "APPLICANT_SURNAME" },
        { "key": "personDocNo", "sourceField": "APPLICANT_DOCUMENT_NO" },
        { "key": "email", "sourceField": "APPLICANT_EMAIL" }
      ],
      "useMultiplePayloadKeys": true,
      "populates": [
        { "valueKey": "can_initiate_status", "targetKey": "CAN_NOW_INITIATE" },
        { "valueKey": "draft_applications", "targetKey": "FETCHED_DRAFT_APPLICATIONS" }
      ]
    },
    "validation": {
      "messages": {
        "invalidInput": "Error retrieving draft status",
        "invalidGenericInput": "A technical issue occurred. Please try again later."
      }
    }
  },
  {
    "key": "DELETE_DRAFT",
    "type": "customconditionaldatafetch",
    "props": {
      "label": "DELETE_DRAFT",
      "url": "/integration/v1/fetch/sync",
      "useBaseUrl": true,
      "endpointCode": "RDB_DELETE_DRAFT_BUSINESS",
      "triggerType": "ON_SUCCESS",
      "onSuccessOf": "CHECK_DRAFT",
      "debounceTime": 500,
      "hideField": true,
      "hideFromPreview": true,
      "required": false,
      "defaultRequired": false,
      "fetchCondition": {
        "field": "CAN_NOW_INITIATE",
        "operator": "NEQ",
        "value": "success",
        "searchInRootForm": false
      },
      "payloadKeyMappings": [
        { "key": "applications", "sourceField": "FETCHED_DRAFT_APPLICATIONS" }
      ],
      "useMultiplePayloadKeys": true
    },
    "validation": {
      "messages": {
        "invalidInput": "Error deleting draft"
      }
    }
  },
  {
    "key": "CREATE_DRAFT_DIRECT",
    "type": "customconditionaldatafetch",
    "props": {
      "label": "CREATE_DRAFT_DIRECT",
      "url": "/integration/v1/fetch/sync",
      "useBaseUrl": true,
      "endpointCode": "RDB_INITIATE_DBR_PUSH_1",
      "triggerType": "ON_SUCCESS",
      "onSuccessOf": "CHECK_DRAFT",
      "debounceTime": 500,
      "hideField": true,
      "hideFromPreview": true,
      "required": false,
      "defaultRequired": false,
      "fetchCondition": {
        "field": "CAN_NOW_INITIATE",
        "operator": "EQ",
        "value": "success",
        "searchInRootForm": false
      },
      "payloadKeyMappings": [
        { "key": "surname", "sourceField": "APPLICANT_SURNAME" },
        { "key": "email", "sourceField": "APPLICANT_EMAIL" }
      ],
      "useMultiplePayloadKeys": true,
      "showGlobalError": true,
      "errorMapping": {
        "detectionType": "advanced",
        "useApiMessage": true,
        "defaultErrorCode": "invalidGenericInput",
        "errorMessagePath": "responseMessage.message"
      },
      "populates": [{ "valueKey": "data.id", "targetKey": "BUSINESS_ID" }]
    },
    "validation": {
      "messages": {
        "invalidInput": "Error creating application",
        "invalidGenericInput": "A technical issue occurred. Please try again later."
      }
    }
  },
  {
    "key": "CREATE_DRAFT_AFTER_DELETE",
    "type": "customconditionaldatafetch",
    "props": {
      "label": "CREATE_DRAFT_AFTER_DELETE",
      "url": "/integration/v1/fetch/sync",
      "useBaseUrl": true,
      "endpointCode": "RDB_INITIATE_DBR_PUSH_1",
      "triggerType": "ON_SUCCESS",
      "onSuccessOf": "DELETE_DRAFT",
      "debounceTime": 500,
      "hideField": true,
      "hideFromPreview": true,
      "required": false,
      "defaultRequired": false,
      "payloadKeyMappings": [
        { "key": "surname", "sourceField": "APPLICANT_SURNAME" },
        { "key": "email", "sourceField": "APPLICANT_EMAIL" }
      ],
      "useMultiplePayloadKeys": true,
      "showGlobalError": true,
      "errorMapping": {
        "detectionType": "advanced",
        "useApiMessage": true,
        "defaultErrorCode": "invalidGenericInput",
        "errorMessagePath": "responseMessage.message"
      },
      "populates": [{ "valueKey": "data.id", "targetKey": "BUSINESS_ID" }]
    },
    "validation": {
      "messages": {
        "invalidInput": "Error creating application",
        "invalidGenericInput": "A technical issue occurred. Please try again later."
      }
    }
  }
]

Common mistakes

  • Omitting url — always set to /integration/v1/fetch/sync; the component throws at runtime if missing.
  • Omitting endpointCode — throws at runtime; always required.
  • Using triggerType: "FIELD_LISTENER" on chained fetches — causes race conditions; only the entry-point fetch should be FIELD_LISTENER; all dependent fetches must use ON_SUCCESS.
  • Using triggerType: "ON_SUCCESS" without setting onSuccessOf — the chain has no anchor and never fires.
  • Omitting useMultiplePayloadKeys: true when payloadKeyMappings contains more than one entry — only the first key is sent to the API.
  • Forgetting hidden status fields that fetchCondition reads — the condition field must exist in the model (typically a hidden input field populated by an earlier populates mapping).
  • Creating circular chains (A waits for B, B waits for A) — infinite wait, fetch never fires.
  • Using customconditionaldatafetch with no fetchCondition and no chaining — use customgenericdatafetch instead.

Checklist

  • key is UPPER_SNAKE_CASE and unique across the entire form
  • props.label matches key (this is a hidden internal field)
  • url is "/integration/v1/fetch/sync" and useBaseUrl: true
  • endpointCode is set
  • triggerType is one of "FIELD_LISTENER", "TRIGGER_BUTTON", or "ON_SUCCESS"
  • onSuccessOf is set whenever triggerType: "ON_SUCCESS"
  • hideField: true (this component has no visible UI)
  • useMultiplePayloadKeys: true whenever payloadKeyMappings has more than one entry
  • Every field referenced in fetchCondition.field exists in the model
  • Chained fetches use ON_SUCCESS, never a second FIELD_LISTENER
  • At least one of fetchCondition or chaining is in use (otherwise prefer customgenericdatafetch)
  • validation.messages includes invalidInput and invalidGenericInput

On this page