Skip to main content

Action Manager

The action classes are an opt-in scaffold for routing product intents such as display, play, and content focus through one application service. Hosanna does not register a default actionManager, and the base handler methods contain no navigation, playback, or analytics behavior.

Use this layer only when your app supplies and registers a concrete manager.

Register a manager

export class AppActionManager extends ActionManager<BaseActionType> {
override handleDisplayAction() {
const item = this.action?.payload?.item as CatalogueItem | undefined;
const origin = this.action?.payload?.origin as BaseView | undefined;
const nav = origin?.getNavController();

if (!item || !nav) {
this.action?.setState(ActionState.Failed);
this.action?.setFinishState(ActionState.Failed);
return;
}

nav.push(DetailsScreen({ item }));
this.action?.setState(ActionState.Completed);
}
}

export class App extends BaseApp {
protected override getCustomIOCServices(): IOCServiceMap {
return [
{ key: 'actionManager', clazz: AppActionManager },
];
}
}

BaseView.dispatchAction() requires that registration. It creates an HsAction, adds the dispatching view as payload.origin when a payload exists, and passes the action to the manager:

const action = this.dispatchAction({
actionType: BaseActionType.Display,
payload: { item },
});

If payload is omitted, no origin object is created automatically. Include a payload whenever the manager needs the source view.

Built-in action types

BaseActionType contains:

  • None
  • Display
  • DisplayAndPlay
  • Play
  • PlayLive
  • ContentFocusIn
  • ContentBlur
  • ContentClick

The base manager routes these to overridable handler methods. DisplayAndPlay currently calls handleDisplayAction(); implement any follow-on play behavior in your subclass.

For a custom action-type union or enum, override manageAction() so the manager can route those values. The base switch marks unknown types as Error.

Action lifecycle

HsAction extends HsObservable and publishes two fields:

FieldPurpose
stateImmediate handling result.
finishStateOptional later outcome, such as playback completion.

Both start at ActionState.Pending. Other values are Completed, Failed, and Error.

action.setState(ActionState.Completed);

// Later, when the launched experience ends:
action.setFinishState(ActionState.Completed);

setState() and setFinishState() only change a field while that field is still Pending. Repeated terminal updates are ignored.

Cancellation is not implemented by the base class

ActionManager.cancelPendingAction() currently logs a pending action but does not change its state or cancel underlying work. Override it if a new action must supersede or cancel an older one.

Likewise, base handler methods are empty. A true result from handleAction() means the base routing path ran; it does not prove that a screen opened, playback started, analytics fired, or a pending action reached a terminal state. Your subclass owns those guarantees.

Talk to us