waitActionType method

  1. @visibleForTesting
Future<ReduxAction<St>?> waitActionType(
  1. Type actionType, {
  2. bool completeImmediately = false,
  3. int? timeoutMillis,
})

Returns a future that completes when an action of the given type in NOT in progress (it's not being dispatched):

  • If NO action of the given type is currently in progress when the method is called, and completeImmediately is false (the default), this method will throw an error.

  • If NO action of the given type is currently in progress when the method is called, and completeImmediately is true, the future completes immediately, returns null, and throws no error.

  • If an action of the given type is in progress, the future completes when the action finishes, and returns the action. You can use the returned action to check its status:

    var action = await store.waitActionType(MyAction);
    expect(action.status.originalError, isA<UserException>());
    

You may also provide a timeoutMillis, which by default is 10 minutes. To disable the timeout, make it -1. If you want, you can modify defaultTimeoutMillis to change the default timeout.

Examples:

// Dispatches an actions that changes the state, then await for the state change:
expect(store.state.name, 'John')
dispatch(ChangeNameAction("Bill"));
var action = await store.waitCondition((state) => state.name == "Bill");
expect(action, isA<ChangeNameAction>());
expect(store.state.name, 'Bill');

// Dispatches actions and wait until no actions are in progress.
dispatch(BuyStock('IBM'));
dispatch(BuyStock('TSLA'));
await waitAllActions([]);
expect(state.stocks, ['IBM', 'TSLA']);

// Dispatches two actions in PARALLEL and wait for their TYPES:
expect(store.state.portfolio, ['TSLA']);
dispatch(BuyAction('IBM'));
dispatch(SellAction('TSLA'));
await store.waitAllActionTypes([BuyAction, SellAction]);
expect(store.state.portfolio, ['IBM']);

// Dispatches actions in PARALLEL and wait until no actions are in progress.
dispatch(BuyAction('IBM'));
dispatch(BuyAction('TSLA'));
await store.waitAllActions([]);
expect(store.state.portfolio.containsAll('IBM', 'TSLA'), isFalse);

// Dispatches two actions in PARALLEL and wait for them:
let action1 = BuyAction('IBM');
let action2 = SellAction('TSLA');
dispatch(action1);
dispatch(action2);
await store.waitAllActions([action1, action2]);
expect(store.state.portfolio.contains('IBM'), isTrue);
expect(store.state.portfolio.contains('TSLA'), isFalse);

// Dispatches two actions in SERIES and wait for them:
await dispatchAndWait(BuyAction('IBM'));
await dispatchAndWait(SellAction('TSLA'));
expect(store.state.portfolio.containsAll('IBM', 'TSLA'), isFalse);

// Wait until some action of a given type is dispatched.
dispatch(DoALotOfStuffAction());
var action = store.waitActionType(ChangeNameAction);
expect(action, isA<ChangeNameAction>());
expect(action.status.isCompleteOk, isTrue);
expect(store.state.name, 'Bill');

// Wait until some action of the given types is dispatched.
dispatch(ProcessStocksAction());
var action = store.waitAnyActionTypeFinishes([BuyAction, SellAction]);
expect(store.state.portfolio.contains('IBM'), isTrue);

See also: waitCondition - Waits until the state is in a given condition. waitActionCondition - Waits until the actions in progress meet a given condition. waitAllActions - Waits until the given actions are NOT in progress, or no actions are in progress. waitActionType - Waits until an action of a given type is NOT in progress. waitAllActionTypes - Waits until all actions of the given type are NOT in progress. waitAnyActionTypeFinishes - Waits until ANY action of the given types finish dispatching.

You should only use this method in tests.

Implementation

@visibleForTesting
Future<ReduxAction<St>?> waitActionType(
  Type actionType, {
  bool completeImmediately = false,
  int? timeoutMillis,
}) async {
  var (_, triggerAction) = await this.waitActionCondition(
    completeImmediately: completeImmediately,
    completedErrorMessage: "No action of the given type was in progress",
    timeoutMillis: timeoutMillis,
    //
    (actionsInProgress, triggerAction) {
      return !actionsInProgress.any((action) => action.runtimeType == actionType);
    },
  );

  return triggerAction;
}