An input field that fires an API lookup — either through the Irembo gateway (customgenericdatafetch) or directly to any URL (customdirectdatafetch) — and maps the response into other form fields via the populates array.
Read Form Rules before using this component — keys, labels, required fields, expressions, visibility, and validation all follow shared conventions.
| Scenario |
Use |
Lookup goes through the Irembo API gateway using a configured endpointCode |
customgenericdatafetch |
| Lookup calls a target URL directly with a configurable HTTP method and path/query params |
customdirectdatafetch |
| User must click a standalone button to trigger the lookup (no input field) |
genericbuttonfetch |
| Instead of this, use… |
For… |
customidinput |
NID / Foreigner ID / Child ID / NIN with built-in NIDA verification |
customtininput |
Company TIN with built-in RDB/RRA verification |
Type string: customgenericdatafetch
triggerType |
When the fetch fires |
INPUT_LENGTH |
When the typed value reaches genericInputLength characters |
TRIGGER_BUTTON |
When the irembogov-button-trigger-wrapper sets props.runAction = true |
FIELD_LISTENER |
When another field (identified by payloadKey or payloadKeyMappings[].sourceField) changes value |
ON_SUCCESS |
After another customgenericdatafetch emits a success event |
| Prop |
Type |
Required? |
Description |
label |
string |
required |
Visible label. Must be unique across the form. |
required |
boolean |
required |
Always false. The expression controls the runtime value. |
defaultRequired |
boolean |
required |
true for required fields, false for optional ones. |
url |
string |
required |
Gateway endpoint path. Almost always "/integration/v1/fetch/sync". |
endpointCode |
string |
required |
Integration endpoint code sent in the gateway request payload. |
triggerType |
string |
required |
One of "INPUT_LENGTH", "TRIGGER_BUTTON", "FIELD_LISTENER", "ON_SUCCESS". |
useBaseUrl |
boolean |
required |
Always true — prepends the API gateway base URL. |
populates |
array |
required |
{ valueKey, targetKey } pairs mapping response paths to form field keys. |
payloadKey |
string |
conditional |
Form field key whose value is sent as the request payload (single-key mode). |
useMultiplePayloadKeys |
boolean |
optional |
When true, use payloadKeyMappings instead of payloadKey. |
payloadKeyMappings |
array |
conditional |
Array of { key, sourceField, isStatic } or { key, staticValue, isStatic: true } entries when useMultiplePayloadKeys is true. |
genericInputLength |
number |
conditional |
Minimum character count to trigger the fetch when triggerType is "INPUT_LENGTH". |
debounceTime |
number |
optional |
Milliseconds to wait after the last input change before firing. Defaults to 500. |
errorMapping |
object |
optional |
Error handling configuration: { detectionType, useApiMessage, defaultErrorCode, errorMessagePath }. |
showGlobalError |
boolean |
optional |
When true, displays fetch errors in the form's global error area. |
hideFromPreview |
boolean |
optional |
When true, excludes this field from the submission preview panel. |
populateRelativeToRootForm |
boolean |
optional |
When false, populates target keys are resolved within the current repeater scope. Defaults to true (global). |
disableFirstFetchOnRFA |
boolean |
optional |
Skips the initial fetch when the form is in Request For Amendment state. |
numericOnly |
boolean |
optional |
Restricts input to digits only. |
successMessage |
string |
optional |
Message displayed on successful fetch. |
placeholder |
string |
optional |
Input placeholder text. |
hideField |
boolean |
optional |
Hides the field and excludes its value. Toggle via expressions["props.hideField"]. |
| Key |
When it fires |
required |
Field is empty on submit |
invalidGenericInput |
Fetch failed or returned no result |
invalidId |
Fetch returned an error response |
invalidInput |
Input format did not meet requirements |
{
"key": "EMPLOYER_LOOKUP",
"type": "customgenericdatafetch",
"props": {
"label": "Employer ID",
"required": false,
"defaultRequired": true,
"url": "/integration/v1/fetch/sync",
"endpointCode": "EMPLOYER_LOOKUP",
"useBaseUrl": true,
"triggerType": "INPUT_LENGTH",
"genericInputLength": 9,
"payloadKey": "EMPLOYER_ID",
"populates": [
{ "valueKey": "data.companyName", "targetKey": "COMPANY_NAME" },
{ "valueKey": "data.address", "targetKey": "ADDRESS" }
]
},
"expressions": {
"props.required": "!(field?.props?.hideField || field?.hide) && field?.props?.defaultRequired"
},
"validation": {
"messages": {
"required": "Employer ID is required",
"invalidGenericInput": "Employer not found"
}
}
}
{
"key": "OWNER_DETAILS_FETCH",
"type": "customgenericdatafetch",
"props": {
"label": "Owner Details",
"required": false,
"defaultRequired": false,
"url": "/integration/v1/fetch/sync",
"endpointCode": "FETCH_OWNER_DETAILS",
"useBaseUrl": true,
"triggerType": "FIELD_LISTENER",
"debounceTime": 500,
"useMultiplePayloadKeys": true,
"payloadKeyMappings": [
{ "key": "documentNumber", "sourceField": "DOCUMENT_NUMBER", "isStatic": false }
],
"populates": [
{ "valueKey": "data.ownerName", "targetKey": "OWNER_NAME" },
{ "valueKey": "data.ownerAddress", "targetKey": "OWNER_ADDRESS" }
],
"hideField": true,
"hideFromPreview": true,
"showGlobalError": true
},
"expressions": {
"props.hideField": "!model?.DOCUMENT_NUMBER",
"props.required": "!(field?.props?.hideField || field?.hide) && field?.props?.defaultRequired"
},
"validation": {
"messages": {
"invalidGenericInput": "Owner details could not be retrieved"
}
}
}
- Omitting
endpointCode — the component throws at runtime.
- Setting
useMultiplePayloadKeys: true without payloadKeyMappings — the fetch fires with an empty payload.
- Using
payloadKey when useMultiplePayloadKeys: true — only payloadKeyMappings is read in multi-key mode.
FIELD_LISTENER pointing to a non-existent field — the listener finds no control to watch; the fetch never fires.
TRIGGER_BUTTON without props.runAction: false and props.runningAction: false — the fetch may fire unexpectedly on load.
- Wrong
populates.valueKey path — the gateway wraps the payload; use "data.fieldName" unless the endpoint returns the value at root.
Type string: customdirectdatafetch
All props from customgenericdatafetch apply. Use this when the fetch must call a URL directly instead of the Irembo API gateway.
| Prop |
Type |
Required? |
Description |
httpMethod |
string |
required (for direct mode) |
HTTP verb: "GET", "POST", "PUT", "PATCH", "DELETE". Activates direct mode; bypasses the gateway. |
pathParams |
array |
optional |
Replaces path variables in url. Each entry: { "key": "varName", "value": "staticValue" } or { "key": "varName", "sourceField": "formFieldKey" }. Matches :varName or {varName} in the URL. |
queryParams |
array |
optional |
Appends query string parameters. Same shape as pathParams. |
bodyMappings |
array |
optional |
Builds the POST/PUT/PATCH request body from static values or form fields. |
{
"key": "VEHICLE_INFO",
"type": "customdirectdatafetch",
"props": {
"label": "Vehicle Registration Number",
"required": false,
"defaultRequired": true,
"url": "/registry/v1/vehicles/{plateNumber}",
"httpMethod": "GET",
"useBaseUrl": true,
"triggerType": "INPUT_LENGTH",
"genericInputLength": 7,
"pathParams": [{ "key": "plateNumber", "sourceField": "VEHICLE_INFO" }],
"populates": [
{ "valueKey": "make", "targetKey": "VEHICLE_MAKE" },
{ "valueKey": "model", "targetKey": "VEHICLE_MODEL" }
]
},
"expressions": {
"props.required": "!(field?.props?.hideField || field?.hide) && field?.props?.defaultRequired"
},
"validation": {
"messages": {
"required": "Vehicle registration number is required",
"invalidGenericInput": "Vehicle registration not found"
}
}
}
- Omitting
httpMethod — the component falls back to gateway mode and requires endpointCode; without either it throws.
- Forgetting path variable placeholders in
url — use :key or {key} in the URL; plain URLs receive no substitution.
pathParams[].sourceField pointing to a key that returns null — the resolved URL contains the string "null", causing a 404.