Objective Redux

Redux made better, objectively.

StatelessController

abstract class StatelessController extends Controller

Create and manage sagas that are associated with an objectiveStore.

Examples

class SwitchStateController extends StatelessController {
 getName() {
   return 'switch';
 }

 toggleSwitch = this.createSagaAction(
   function* () {
     const controller = yield getControllerFromSagaContext(SwitchStateController);
     yield controller.toggleSwitchValue();
     yield controller.incrementCount();
   }
 )
   .withAddressableName('MY_ACTION')
   .withEffect(configureTakeLatest())
   .register();
}

const instance = SwitchStateController.getInstance(objectiveStore);
instance.toggleSwitch();

objectiveStore

protected objectiveStore: ObjectiveStore|null

The ReduxController to which the controller belongs.

constructor

public constructor(): StatelessController

ObjectiveStores and starts the sagas.
WARNING: While the constructor can be called directly, controllers are meant to be initialized with the [[getInstance]] method. Creating instances directly can lead to having more than one instance at a time, which may have adverse affects on the application.

Returns

StatelessController
An instance of the StatelessController.

createActionName

protected createActionName(name: string|null = null): string

Generates a unique, default action name.

Parameters

name: string|null = null
The name of the action or null to generate a unique, default action name.

Returns

string
An action name.

createSagaAction

protected createSagaAction<Payload>(sagaFn: SagaFn<Payload>): SagaBuilder<Payload>

Creates an instance of a [[SagaBuilder]] that will be registered when the builder finishes.

Template Parameters

<Payload>
The payload the action and the saga will take. If void, no action is expected.
This template variable is optional.

Parameters

sagaFn: SagaFn<Payload>
The saga function to add to the ObjectiveStore.

Returns

SagaBuilder
A builder that registers the saga.

setObjectiveStore

public setObjectiveStore(objectiveStore: ObjectiveStore): void

Parameters

objectiveStore: ObjectiveStore

Returns

void

getInstance

public static getInstance<T>(this: Controller|ModelConstructor<T>, objectiveStore: ObjectiveStore): T

Gets an instance of the class, creating one if it does not yet exist.
This should be used as the method of instantiating controllers.

Template Parameters

<T>
The controller type. Will be inferred from the class instance and does not need to be provided.

Parameters

this: Controller|ModelConstructor<T>
Implicit "this" for internal use. When calling, this parameter should be ignored/skipped.

objectiveStore: ObjectiveStore
An instance of the ObjectiveStore from which to get the controller.

Returns

T
An instance of the controller.

Examples

const instance = MyController.getInstance(objectiveStore);

getName

public static getName(): string

Gets the unique name of the controller. By default, the name of the class.
The name of the controller should be globally unique for all Objective Redux controllers in the application.

Returns

string
The name of the state slice.

getNamespace

public static getNamespace(): string|null

Creates groupings of controllers and state slices. This helps prevent naming collisions, because names only need to be unique within a namespace.
In addition, for StateControllers, the slice of state in the store is also saved into an object of the namespace name. Note that falsy values like null and '' will evaluate to the same empty namespace.

Returns

string|null
Null if the state is not namespaced.

Examples

// For StateControllers, the namespace also groups slices in the store.

class MyFirstController extends StateController {
  // ...

  static getName() {
    return 'MY_FIRST_CONTROLLER';
  }

  static getNamespace() {
    return 'MY_NAMESPACE';
  }

  // ...
}

class MySecondController extends StateController {
  // ...

  static getName() {
    return 'MY_SECOND_CONTROLLER';
  }

  static getNamespace() {
    return 'MY_NAMESPACE';
  }

  // ...
}

// Creates a state of the form:
//
// {
//   MY_NAMESPACE: {
//     MY_FIRST_CONTROLLER: {
//       // ...
//     },
//     MY_SECOND_CONTROLLER: {
//       // ...
//     },
//   },
// }

initializeOnExternalAction

public static initializeOnExternalAction<T>(this: T): void

Allows the controller to be lazy loaded by actions triggered outside of Objective Redux.
In order for calls to be routed to the controller without using the controller directly, and thus to lazy-load without using the controller directly, this needs to be used in conjunction with the method [[withAddressableName]].

Template Parameters

<T>

Parameters

this: T
Implicit "this" parameter, which does not need to be supplied.

Returns

void

Examples

class MyController extends StateController<MySliceType> {
  public static getName() {
    return 'MY_CONTROLLER';
  }

  action = this.createReducingAction(
    (state, payload) => ({
      ...state,
      ...payload,
    })
  ).withAddressableName('MY_ACTION'); // <-- also required
}

MyController.initializeOnExternalAction();

export MyController;

// ... elsewhere ...

// By firing this action, the controller will now be instantiated (if it hasn't been).
const myAction = createAction(getActionNameForController('MY_CONTROLLER', 'MY_ACTION'));
objectiveStore.dispatch(myAction);

removeInstance

public static removeInstance<T>(this: Controller|ModelConstructor<T>, objectiveStore: ObjectiveStore): void

Removes the instance of the controller from the store. This will unregister reducers any stop saga associated with the controller.

Template Parameters

<T>

Parameters

this: Controller|ModelConstructor<T>
Implicit "this" for internal use. When calling, this parameter should be ignored/skipped.

objectiveStore: ObjectiveStore
An instance of the ObjectiveStore from which to get the controller.

Returns

void

Examples

MyController.removeInstance(objectiveStore);