isWaiting method

bool isWaiting(
  1. Object actionOrActionTypeOrList
)

You can use isWaiting and pass it actionOrActionTypeOrList to check if:

  • A specific async ACTION is currently being processed.
  • An async action of a specific TYPE is currently being processed.
  • If any of a few given async actions or action types is currently being processed.

If you wait for an action TYPE, then it returns false when:

  • The ASYNC action of the type is NOT currently being processed.
  • If the type is not really a type that extends ReduxAction.
  • The action of the type is a SYNC action (since those finish immediately).

If you wait for an ACTION, then it returns false when:

  • The ASYNC action is NOT currently being processed.
  • If the action is a SYNC action (since those finish immediately).

Trying to wait for any other type of object will return null and throw a StoreException after the async gap.

Examples:

// Waiting for an action TYPE:
dispatch(MyAction());
if (store.isWaiting(MyAction)) { // Show a spinner }

// Waiting for an ACTION:
var action = MyAction();
dispatch(action);
if (store.isWaiting(action)) { // Show a spinner }

// Waiting for any of the given action TYPES:
dispatch(BuyAction());
if (store.isWaiting([BuyAction, SellAction])) { // Show a spinner }

Implementation

bool isWaiting(Object actionOrActionTypeOrList) {
  //
  // 1) If a type was passed:
  if (actionOrActionTypeOrList is Type) {
    _awaitableActions.add(actionOrActionTypeOrList);
    return _actionsInProgress.any((action) => action.runtimeType == actionOrActionTypeOrList);
  }
  //
  // 2) If an action was passed:
  else if (actionOrActionTypeOrList is ReduxAction) {
    _awaitableActions.add(actionOrActionTypeOrList.runtimeType);
    return _actionsInProgress.contains(actionOrActionTypeOrList);
  }
  //
  // 3) If an iterable was passed:
  // 3.1) For each action or action type in the iterable...
  else if (actionOrActionTypeOrList is Iterable) {
    bool isWaiting = false;
    for (var actionOrType in actionOrActionTypeOrList) {
      //
      // 3.2) If it's a type.
      if (actionOrType is Type) {
        _awaitableActions.add(actionOrType);

        // 3.2.1) Is waiting if any of the actions in progress has that exact type.
        if (!isWaiting)
          isWaiting = _actionsInProgress.any((action) => action.runtimeType == actionOrType);
      }
      //
      // 3.3) If it's an action.
      else if (actionOrType is ReduxAction) {
        _awaitableActions.add(actionOrType.runtimeType);

        // 3.3.1) Is waiting if any of the actions in progress is the exact action.
        if (!isWaiting) isWaiting = _actionsInProgress.contains(actionOrType);
      }
      //
      // 3.4) If it's not an action and not an action type, throw an exception.
      // The exception is thrown after the async gap, so that it doesn't interrupt the processes.
      else {
        Future.microtask(() {
          throw StoreException(
              "You can't do isWaiting([${actionOrActionTypeOrList.runtimeType}]). "
              "Use only actions, action types, or a list of them.");
        });
      }
    }

    // 3.5) If the `for` finished without matching any items, return false (it's NOT waiting).
    return isWaiting;
  }
  // 4) If something different was passed, it's an error. We show the error after the
  // async gap, so we don't interrupt the code. But we return false (not waiting).
  else {
    Future.microtask(() {
      throw StoreException("You can't do isWaiting(${actionOrActionTypeOrList.runtimeType}), "
          "Use only actions, action types, or a list of them.");
    });

    return false;
  }
}