Use derivedProps to populate component values dynamically
Use the UiSdlConnected#derivedProps field to pass dynamic input into a component from the outside. The platform resolves these values at runtime and binds them to internal props such as value, dataRecord, or other configurable fields. This lets components show or update values reactively without hardcoding them into the JSON.
You can use derivedProps to pull values from application state, session metadata, route parameters, or static constants.
Set a hardcoded derived value
Use a string directly in derivedProps to inject a constant value into a field. This is useful for placeholder values or default content when testing.
// ${package}/c3/ui/meta/ExamplePackage.WindTurbineDerivedPropsHardcoded.json
{
"type": "UiSdlConnected<UiSdlTextField>",
"derivedProps": {
"value": "hardcoded value"
}
}This sets the field’s value to "hardcoded value" when the component loads.
Reference a value from component state
Use UiSdlApplicationStateValueParam to read a specific value from application state and bind it to a field.
// ${package}/c3/ui/meta/ExamplePackage.WindTurbineDerivedPropsAppState.json
{
"type": "UiSdlConnected<UiSdlTextField>",
"derivedProps": {
"value": {
"type": "UiSdlApplicationStateValueParam",
"id": "UiPrototype.WindTurbineApplicationState",
"path": "currWindturbine.location"
}
},
"component": {}
}This binds the value to currWindturbine.location, which is defined in the application state below.
// ${package}/c3/ui/meta/ExamplePackage.WindTurbineApplicationState.json
{
"type": "WindTurbineApplicationState",
"currWindturbine": {
"id": "1",
"location": "Boston"
}
}Reference a full record from application state and use it in a form
When working with forms, you can bind an entire object to dataRecord and use dataPropSpecs to map fields individually.
This example shows how to populate a form field with data from WindTurbineApplicationState. It reads values from WindTurbineApplicationState.currWindturbine and displays them using derivedProps. The location field uses a UiSdlTextInput and binds its value from the application state.
// ${package}/c3/ui/meta/ExamplePackage.WindTurbineDerivedProps.json
{
"type": "UiSdlConnected<UiSdlForm>",
// derivedProps defines the source of dynamic inputs to the form
"derivedProps": {
"dataRecord": {
"type": "UiSdlApplicationStateValueParam", // Reads a value from application state
"id": "UiPrototype.WindTurbineApplicationState", // The ID of the application state object
"path": "currWindturbine" // Path to the specific object in state
}
},
"component": {
"title": {
"title": "Derived Props Form"
},
"clearOnCancel": true,
// dataSpec defines which fields the form uses and how they map to the input
"dataSpec": {
"fieldSets": {
"type": "[UiSdlFormFieldSet]",
"value": [
{
"type": "UiSdlFormFieldSet",
"title": "Edit location",
"fields": [
{
"fieldName": "location", // Field name inside dataRecord
"label": "Location",
"required": true,
"inputElement": {
"type": "UiSdlTextInput"
},
// dataPropSpecs maps a form input property to a path in dataRecord
"dataPropSpecs": [
{
"prop": "value", // The property to bind (input value)
"dataPath": "location" // The path to use from dataRecord
}
]
}
]
}
]
}
}
}
}This binds the dataRecord to the full currWindturbine object and binds the location input field to dataRecord.location.
Define the application state that stores the data
Define a shared application state object that stores the turbine record. Other components can update or read from this shared object.
// ${package}/c3/ui/meta/examplePackage.WindTurbineApplicationState.json
{
"type": "WindTurbineApplicationState",
// Initial state value for currWindturbine
"currWindturbine": {
"id": "1",
"location": "Boston"
}
}Create the application state Type
Define the shape and behavior of your application state using a .c3typ Type. This example defines one field, an update action, and a reducer to modify it.
This Type defines the structure and behavior of the application state. It mixes UiSdlApplicationState and declares three required fields:
currWindTurbine: The active turbine objectupdateUserAction: An action creator to update that objectuserUpdateReducer: A reducer that modifies state in response to the action
@typeScript
type WindTurbineApplicationState mixes UiSdlApplicationState {
currWindTurbine: json
@uiSdlActionCreator(actionType='UPDATE_WIND_TURBINE')
updateUserAction: private function(stateId: string, newHeaderText: string): UiSdlReduxAction ts-client
@uiSdlReducer(actionType='UPDATE_WIND_TURBINE')
userUpdateReducer: private inline function(state: !UiSdlReduxState,
action: UiSdlReduxAction): UiSdlReduxState ts-client
}Implement the state logic in TypeScript
Implement the state logic in a TypeScript file. This controls how the platform processes updates and stores new values in Redux.
// ${package}/c3/src/WindTurbineApplicationState.ts
import { UiSdlReduxAction } from '@c3/ui/UiSdlReduxAction';
import { ImmutableReduxState } from '@c3/ui/UiSdlConnected';
import { setConfigInApplicationState } from '@c3/ui/UiSdlApplicationState';
export function updateUserAction(stateId: string, newHeaderText: string): UiSdlReduxAction {
return {
type: stateId + '.UPDATE_WIND_TURBINE',
payload: {
stateId,
currWindTurbine: newHeaderText,
},
};
}
export function userUpdateReducer(state: ImmutableReduxState, action: UiSdlReduxAction): UiSdlReduxAction {
return setConfigInApplicationState(
action.payload.stateId,
state,
['currWindTurbine'],
action.payload.currWindTurbine
);
}Use derivedProps to pass external data into a component like UiSdlForm. You can extract values from application state using UiSdlApplicationStateValueParam, define the path to pull data from, and bind those values into your form inputs using dataPropSpecs.
This pattern supports reactive forms that stay in sync with user actions, global state, or external inputs—without hardcoding any data directly in the form.