<DynamicBuilder>
Overview
The <DynamicBuilder> component creates a stateful widget that handles asynchronous data
loading and rebuilding. It intelligently works with Future (one-time async loads),
Stream (continuous updates), or static values, automatically managing loading states,
errors, and UI rebuilds.
If you need view-model business logic beyond simple data loading, use a <Controller> instead.
The component automatically:
- Supports progress indicator while loading
- Displays errors with appropriate error widgets
- Rebuilds the UI when data arrives or changes
- Manages the lifecycle of async operations
Use Cases
- Loading data from APIs or databases
- Displaying real-time data from streams
- Handling asynchronous initialization
- Building dynamic lists with lazy-loaded data
- Managing complex data dependencies
Attributes
| Name | Type | Description | Required | Default |
|---|---|---|---|---|
builder |
Function | Function that builds the widget tree with the loaded data. Signature: (BuildContext, Dependencies, T data) => Widget |
Yes | - |
initValue |
dynamic | Initial value to use. Can be a Future, Stream, object, or primitive. Mutually exclusive with initializer. |
No | null |
initializer |
Function | Function that returns the initial value. Signature: (BuildContext, Dependencies) => dynamic. Can return Future, Stream, object, or primitive. Mutually exclusive with initValue. |
No | null |
errorWidget |
Widget | Widget to display if an error occurs during loading or building | No | Default error widget |
progressWidget |
Widget | Widget to display while waiting for Future to complete or Stream to emit first value |
No | SizedBox.shrink() |
disposeOfDependencies |
bool | Whether to dispose of dependencies when the widget is disposed | No | false |
key |
Key | Widget key for controlling widget identity | No | null |
for |
String | The name of the parent's attribute that will be assigned this component | No | null |
visible |
bool | Controls widget visibility | No | true |
Important Notes
initValueandinitializerare mutually exclusive - you can only specify one, not both- When using
Future, the builder is called once when the future completes - When using
Stream, the builder is called every time the stream emits a new value - The
builderfunction receives three parameters:BuildContext,Dependencies, and the data value
Example
Future Example
<DynamicBuilder for="body" initValue="${futureOssLicenses()}">
<builder for="builder" vars="_,dependencies, ossLicenses">
<ListView.builder itemCount="${length(ossLicenses)}">
<builder for="itemBuilder" vars="_,index">
<Card elevation="2" shadowColor="#44000000" >
<Column crossAxisAlignment="start">
<Text data="${ossLicenses[index].name}">
<TextStyle for="style" fontWeight="700"/>
</Text>
<Text data="${ossLicenses[index].license}">
<TextStyle for="style" fontWeight="400"/>
</Text>
</Column>
</Card>
</builder>
</ListView.builder>
</builder>
</DynamicBuilder>
See Also
<forEach>- For iterating over collections<ValueListener>- For listening to value changes