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
| Parameter | Type | Required | Description |
|---|---|---|---|
...actionCreators | EffectActionCreator<any, any, any> | string | Yes | One 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
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
ofTypeoperator filters for themyEffectActionaction type. - It ensures that only actions matching the specified type are passed down the pipeline.
Advanced Examples
Filtering Multiple Action Types
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
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
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
-
Support for Action Creators and Strings: Accepts both action creators (e.g.,
myEffectAction) and plain strings (e.g.,'MY_ACTION_TYPE') for flexibility. -
Type-Safe Filtering: Ensures that only actions matching the specified types are allowed through the pipeline, providing type safety when used with
EffectActionCreator. -
Integration with
EffectActionCreator: Works seamlessly with actions created usingcreateEffectAction, allowing filtering by both the main action and its associated.succeededor.failedactions. -
Performance Optimized: Uses a
Setfor 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 callNotes
-
Designed for Modular Applications: The
ofTypeoperator 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.