Skip to main content

Dynamic Options (API calls)

React-Forminate provides powerful dynamic options loading for select fields (with future support for checkboxes and other field types). This feature allows you to fetch options from APIs automatically, with support for dependencies between fields, pagination, and response transformation.

Basic Usage​

Simple API Fetch​

{
fieldId: "countries",
type: "select",
dynamicOptions: {
endpoint: "https://api.example.com/countries",
fetchOnInit: true // Load options when form mounts
}
}

With Response Transformation​

{
fieldId: "users",
type: "select",
dynamicOptions: {
endpoint: "https://api.example.com/users",
transformResponse: (res) =>
res.map(user => ({ label: user.name, value: user.id })),
fetchOnInit: true
}
}

Dynamic Options Configuration​

Core Properties​

PropertyTypeDescriptionDefault
endpointstringAPI endpoint URL (supports template variables like {{fieldId}})required
methodstringHTTP method"GET"
dependsOnstring | string[]Field IDs this field depends onundefined
paramsobjectQuery parameters (values can reference other fields)undefined
headersobjectRequest headersundefined
transformResponsefunctionTransforms API response to option formatundefined
resultPathstringPath to extract data from nested responseundefined
fetchOnInitbooleanFetch options when component mountsfalse
paginationobjectPagination configurationundefined

Dependent Fields​

Create chained selects where options depend on another field's value:

{
fieldId: "state",
type: "select",
dynamicOptions: {
dependsOn: "country", // Watches country field
endpoint: "https://api.example.com/states",
params: {
country: "country" // Uses value from country field
}
}
}

Pagination​

For large datasets, enable pagination:

{
fieldId: "products",
type: "select",
dynamicOptions: {
endpoint: "https://api.example.com/products",
pagination: {
limit: 10,
pageMode: "page", // or "skip"
pageKey: "page", // query param name
limitKey: "limit",
startPage: 1
}
}
}

Advanced Features​

Response Transformation​

Convert API responses to the expected format:

transformResponse: (res) => {
return res.data.items.map(item => ({
label: `${item.firstName} ${item.lastName}`,
value: item.id,
metadata: {
department: item.dept
}
}));
}

Nested Data Extraction​

Extract data from complex responses:

{
dynamicOptions: {
endpoint: "https://api.example.com/data",
resultPath: "results.items" // Extracts res.results.items
}
}

Template Variables​

Use field values in URLs:

{
fieldId: "userDetails",
type: "select",
dynamicOptions: {
endpoint: "https://api.example.com/users/{{userId}}/details",
dependsOn: "userId"
}
}

Complete Example​

import { DynamicForm } from "react-forminate";

const ProductForm = {
formId: "productForm",
fields: [
{
fieldId: "category",
type: "select",
label: "Product Category",
dynamicOptions: {
endpoint: "https://api.example.com/categories",
fetchOnInit: true,
transformResponse: (res) =>
res.map(cat => ({ label: cat.name, value: cat.id }))
}
},
{
fieldId: "product",
type: "select",
label: "Product",
dynamicOptions: {
dependsOn: "category",
endpoint: "https://api.example.com/products",
params: {
categoryId: "category" // Uses value from category field
},
pagination: {
limit: 20,
pageMode: "page",
maxPage: 5
},
transformResponse: (res) =>
res.map(prod => ({
label: prod.title,
value: prod.id,
price: prod.price
}))
}
},
{
fieldId: "variant",
type: "select",
label: "Variant",
dynamicOptions: {
dependsOn: ["category", "product"], // Multiple dependencies
endpoint: "https://api.example.com/products/{{product}}/variants",
transformResponse: (res) =>
res.variants.map(v => ({ label: v.name, value: v.id }))
}
}
]
};

const ProductSelector = () => (
<DynamicForm
formId={ProductForm.formId}
formData={ProductForm}
onSubmit={(values) => console.log(values)}
/>
);
Clicky