DocsOperatorsofType

ofType

The ofType operator filters the elements of an observable sequence of actions based on the specified action types. It works seamlessly with effect actions (EffectActionCreator), standard Redux actions, or plain strings representing action types.

This operator is different from the redux-observable operator. It supports both action creators and plain strings as input.


Importing

To use the ofType operator, import it from @blue-functor/remodel:

import { ofType } from '@blue-functor/remodel';

Parameters

ParameterTypeRequiredDescription
...actionCreatorsEffectActionCreator<any, any, any> | stringYesOne or more action creators or plain strings representing action types to filter the observable sequence by.

Returns

An OperatorFunction<Action, Action> that filters actions in the observable stream by matching their type property to the specified action creators or strings.


Example Usage

src/models/ui/epics.ts
import { ofType, Epic } from '@blue-functor/remodel';
import { myEffectAction } from '../actions';
import { map } from 'rxjs/operators';
 
const myEpic: Epic = (action$) =>
  action$.pipe(
    ofType(myEffectAction),
    map((action) => {
      console.log('Filtered Action:', action);
      return action;
    }),
  );

In this example:

  • The ofType operator filters for the myEffectAction action type.
  • It ensures that only actions matching the specified type are passed down the pipeline.


Advanced Examples

Filtering Multiple Action Types

src/models/user/epics.ts
import { ofType } from '@blue-functor/remodel';
import { fetchUser, updateUser, deleteUser } from './actions';
 
const userEpic: Epic = (action$) =>
  action$.pipe(
    // Filter for any of these actions
    ofType(fetchUser, updateUser, deleteUser),
    map((action) => {
      console.log('User action:', action.type);
      return action;
    }),
  );

Filtering Success/Failure Actions

src/models/posts/epics.ts
import { ofType } from '@blue-functor/remodel';
import { createPost } from './actions';
import { showNotification } from '../notifications/actions';
 
const notificationEpic: Epic = (action$) =>
  action$.pipe(
    // Filter for succeeded and failed actions
    ofType(createPost.succeeded, createPost.failed),
    map((action) =>
      action.type.endsWith('SUCCEEDED')
        ? showNotification({ message: 'Post created!', type: 'success' })
        : showNotification({ message: 'Failed to create post', type: 'error' })
    ),
  );

Mixing Action Creators and Strings

src/models/mixed/epics.ts
import { ofType } from '@blue-functor/remodel';
import { myAction } from './actions';
 
const mixedEpic: Epic = (action$) =>
  action$.pipe(
    // Mix action creators and string types
    ofType(myAction, '@/CUSTOM_ACTION', myAction.succeeded),
    map((action) => {
      // Handle any of the specified action types
      return processAction(action);
    }),
  );

Features

  1. Support for Action Creators and Strings: Accepts both action creators (e.g., myEffectAction) and plain strings (e.g., 'MY_ACTION_TYPE') for flexibility.

  2. Type-Safe Filtering: Ensures that only actions matching the specified types are allowed through the pipeline, providing type safety when used with EffectActionCreator.

  3. Integration with EffectActionCreator: Works seamlessly with actions created using createEffectAction, allowing filtering by both the main action and its associated .succeeded or .failed actions.

  4. Performance Optimized: Uses a Set for O(1) action type lookups instead of array iteration, ensuring optimal performance even with many action types.


Best Practices

Do

// Filter for specific actions
ofType(fetchUser, updateUser);
 
// Filter for success/failure variants
ofType(fetchUser.succeeded, fetchUser.failed);
 
// Combine with other operators
action$.pipe(
  ofType(myAction),
  map(action => action.payload),
  filter(payload => payload.isValid),
);

Don’t

// Don't manually check action.type - use ofType
action$.pipe(
  filter(action => action.type === myAction.type), // ❌ Use ofType instead
);
 
// Don't create action objects in filter
ofType(myAction()); // ❌ Pass the action creator, not a call

Notes

  • Designed for Modular Applications: The ofType operator is particularly useful in modularized applications where epics are scoped to specific models.

  • Works Out of the Box: It is fully compatible with the system epics and reducers provided by @blue-functor/remodel.

  • Performance: Uses Set.has() for O(1) lookup performance, making it efficient even when filtering for many action types.

  • Type Safety: TypeScript will infer the correct action types when using action creators, providing excellent IDE autocomplete and type checking.

The ofType operator is a powerful utility for handling side effects in a Redux-Observable pipeline, offering flexibility, type safety, and integration with effect actions.