Skip to main content

Action Result + Refresh

Every DYONA action returns the same public result contract:

type DyonaActionRefreshTarget = {
sourceId: string;
};

type DyonaActionResult<TData = unknown> = {
success: boolean;
message?: string;
fieldErrors?: Record<string, string>;
data?: TData;
refresh?: DyonaActionRefreshTarget[];
};

Result properties​

  • success is required. It is a boolean that indicates the logical result of the action.

  • message is optional. It is a string that the consuming UI can use.

  • data is optional and generic. DYONA does not impose its structure. For example:

    data: {
    id: 1024,
    status: 'rejected',
    }
  • refresh is optional and declarative. For example:

    refresh: [
    {sourceId: 'orders'},
    {sourceId: 'dashboard'},
    ]

    It means: “These logical sources may have become stale.” It does not mean that Action Engine reloads them automatically.

Action Feedback in DyonaForm​

When onSubmit or a custom onAction returns a DyonaActionResult, DyonaForm presents the result without requiring a manual Alert.

Success​

{success: true, message: 'Record saved successfully.'}

Shows success feedback that closes automatically. Without message, DYONA uses its localized generic success message.

General error​

{success: false, message: 'The operation could not be completed.'}

Shows persistent error feedback that the user may close manually.

Field error​

{
success: false,
message: 'The record could not be saved.',
fieldErrors: {name: 'This name already exists.'},
}

fieldErrors are applied to the existing field validation and error summary. They remain visible while the user edits and are cleared when a new valid submit or custom action begins. A handler returning void keeps the previous behavior; a thrown technical error is not converted into success: false.

Try Action Feedback in the Lab →

Architecture​

Action executor
↓
DyonaActionResult
↓
refresh: [{sourceId: 'orders'}]
↓
Consumer / future orchestrator
decides how to react

Action Engine validates refresh, transports it, and returns the same result produced by the executor.

Action Engine does not:

  • execute a refresh;
  • call executeDyonaDataSource;
  • know DyonaGrid or DyonaScreen;
  • search for mounted components;
  • use Redux, an Event Bus, or Context to refresh;
  • deduplicate targets.

Runtime rules​

  • refresh is optional.
  • When present, it must be a non-empty array.
  • Each item must be an object.
  • sourceId must be a non-empty string.
  • Validation uses the value after trim.
  • The engine does not modify or normalize sourceId.
  • Repeated targets are allowed.
  • refresh may also be present when success: false.
  • context.sourceId does not automatically become a refresh target.

Successful result​

const executor: DyonaActionExecutor = async () => ({
success: true,
message: 'Order rejected',
data: {
id: 1024,
status: 'rejected',
},
refresh: [
{sourceId: 'orders'},
],
});

A failed result can still refresh​

This is also valid:

{
success: false,
message: 'The operation was only partially completed',
refresh: [
{sourceId: 'orders'},
],
}

An operation can partially fail while still changing data, so a consumer may need to react to its refresh targets.

Relation to Action Dialog​

DyonaActionDialog does not process refresh. It passes the complete DyonaActionResult to onResult(result) without removing message, fieldErrors, data, or refresh.

The current Action Dialog Lab example already demonstrates this with refresh: [{sourceId: 'orders'}].

Continue with Action Engine or Action Dialog.

See Result + Refresh in the Action Dialog Lab