or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

actions-filtering.mdadvanced-features.mdeffect-creation.mdindex.mdmodule-setup.mdtesting.md
tile.json

tessl/npm-ngrx--effects

Side effect model for @ngrx/store that manages asynchronous operations and external interactions in Angular applications using RxJS

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/@ngrx/effects@20.0.x

To install, run

npx @tessl/cli install tessl/npm-ngrx--effects@20.0.0

index.mddocs/

@ngrx/effects

NgRx Effects is a side effect model for @ngrx/store that provides RxJS-powered effect management for Angular applications. It allows for handling asynchronous operations and external interactions while maintaining separation of concerns between pure state logic and side effects.

Package Information

  • Package Name: @ngrx/effects
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install @ngrx/effects

Core Imports

import {
  createEffect,
  Actions,
  ofType,
  EffectsModule,
  provideEffects,
  mergeEffects,
  getEffectsMetadata
} from "@ngrx/effects";

Basic Usage

import { Injectable } from "@angular/core";
import { Actions, createEffect, ofType } from "@ngrx/effects";
import { map, switchMap } from "rxjs/operators";
import { of } from "rxjs";

@Injectable()
export class UserEffects {
  constructor(private actions$: Actions) {}

  // Class-based effect
  loadUsers$ = createEffect(() =>
    this.actions$.pipe(
      ofType(UserActions.loadUsers),
      switchMap(() =>
        this.userService.getUsers().pipe(
          map(users => UserActions.loadUsersSuccess({ users })),
          catchError(error => of(UserActions.loadUsersFailure({ error })))
        )
      )
    )
  );
}

// Functional effect
export const loadUsersEffect = createEffect(
  (actions$ = inject(Actions)) =>
    actions$.pipe(
      ofType(UserActions.loadUsers),
      switchMap(() =>
        inject(UserService).getUsers().pipe(
          map(users => UserActions.loadUsersSuccess({ users }))
        )
      )
    ),
  { functional: true }
);

Architecture

NgRx Effects is built around several key components:

  • Effect Creation: createEffect() function for defining effects with metadata
  • Action Stream: Actions service providing access to all dispatched actions
  • Action Filtering: ofType() operator for type-safe action filtering
  • Module Integration: EffectsModule for module-based setup, provideEffects() for standalone apps
  • Lifecycle Management: Hooks for controlling effect registration and execution
  • Error Handling: Built-in error handling with retry mechanisms
  • Testing Support: Mock providers and utilities for effect testing

Capabilities

Effect Creation and Management

Core functionality for creating and managing effects, including both class-based and functional patterns.

function createEffect<
  C extends EffectConfig & { functional?: false },
  DT extends DispatchType<C>,
  OTP,
  R extends EffectResult<OT>,
  OT extends ObservableType<DT, OTP>
>(
  source: () => R & ConditionallyDisallowActionCreator<DT, R>,
  config?: C
): R & CreateEffectMetadata;

function createEffect<Source extends () => Observable<unknown>>(
  source: Source,
  config: EffectConfig & { functional: true; dispatch: false }
): FunctionalEffect<Source>;

function createEffect<Source extends () => Observable<Action>>(
  source: Source & ConditionallyDisallowActionCreator<true, ReturnType<Source>>,
  config: EffectConfig & { functional: true; dispatch?: true }
): FunctionalEffect<Source>;

function createEffect<
  Result extends EffectResult<unknown>,
  Source extends () => Result
>(
  source: Source,
  config?: EffectConfig
): (Source | Result) & CreateEffectMetadata;

interface EffectConfig {
  dispatch?: boolean;
  functional?: boolean;
  useEffectsErrorHandler?: boolean;
}

type DispatchType<T> = T extends { dispatch: infer U } ? U : true;
type ObservableType<T, OriginalType> = T extends false ? OriginalType : Action;
type EffectResult<OT> = Observable<OT> | ((...args: any[]) => Observable<OT>);
type ConditionallyDisallowActionCreator<DT, Result> = DT extends false
  ? unknown
  : Result extends EffectResult<infer OT>
  ? OT extends ActionCreator
    ? 'ActionCreator cannot be dispatched. Did you forget to call the action creator function?'
    : unknown
  : unknown;

type FunctionalEffect<
  Source extends () => Observable<unknown> = () => Observable<unknown>
> = Source & FunctionalCreateEffectMetadata;

interface FunctionalCreateEffectMetadata extends CreateEffectMetadata {
  '__@ngrx/effects_create__': EffectConfig & { functional: true };
}

interface CreateEffectMetadata {
  '__@ngrx/effects_create__': EffectConfig;
}

Effect Creation and Management

Actions and Filtering

Action stream management and type-safe action filtering capabilities.

class Actions<V = Action> extends Observable<V> {
  lift<R>(operator?: Operator<V, R>): Observable<R>;
}

function ofType<E extends Extract<A, { type: T }>, A extends Action = Action, T extends string = A['type']>(
  ...allowedTypes: [T, ...T[]]
): OperatorFunction<A, E>;

function ofType<AC extends ActionCreator<string, Creator>, U extends Action = Action>(
  ...allowedTypes: [AC, ...AC[]]
): OperatorFunction<U, ReturnType<AC>>;

Actions and Filtering

Module Setup and Providers

Integration with Angular's module system and standalone applications.

class EffectsModule {
  static forRoot(effects: Type<any>[]): ModuleWithProviders<EffectsRootModule>;
  static forFeature(effects: Type<any>[]): ModuleWithProviders<EffectsFeatureModule>;
}

function provideEffects(
  effects: Array<Type<unknown> | Record<string, FunctionalEffect>>
): EnvironmentProviders;

function provideEffects(
  ...effects: Array<Type<unknown> | Record<string, FunctionalEffect>>
): EnvironmentProviders;

function mergeEffects(...effects: Array<Observable<Action> | (() => Observable<Action>)>): () => Observable<Action>;

function getEffectsMetadata<T extends Record<keyof T, Object>>(instance: T): EffectMetadata<T>[];

Module Setup and Providers

Advanced Features

Lifecycle hooks, error handling, and advanced effect management capabilities.

interface OnIdentifyEffects {
  ngrxOnIdentifyEffects(): string;
}

interface OnRunEffects {
  ngrxOnRunEffects(resolvedEffects$: Observable<EffectNotification>): Observable<EffectNotification>;
}

interface OnInitEffects {
  ngrxOnInitEffects(): Action;
}

type EffectsErrorHandler = <T extends Action>(
  observable$: Observable<T>,
  errorHandler: ErrorHandler
) => Observable<T>;

function defaultEffectsErrorHandler<T extends Action>(
  observable$: Observable<T>,
  errorHandler: ErrorHandler,
  retryAttemptLeft: number = 10
): Observable<T>;

Advanced Features

Testing Utilities

Testing support for effects with mock providers and utilities.

function provideMockActions(source: Observable<any>): FactoryProvider;
function provideMockActions(factory: () => Observable<any>): FactoryProvider;

Import testing utilities:

import { provideMockActions } from "@ngrx/effects/testing";

Testing Utilities

Core Types

interface Action {
  type: string;
}

interface ActionCreator<T extends string = string, C extends Creator = Creator> {
  readonly type: T;
  (...args: any[]): any;
}

interface Creator {
  (...args: any[]): object;
}

interface EffectNotification {
  effect: Observable<any> | (() => Observable<any>);
  propertyName: PropertyKey;
  sourceName: string | null;
  sourceInstance: any;
  notification: ObservableNotification<Action | null | undefined>;
}

interface EffectSources {
  addEffects(effectSourceInstance: any): void;
  toActions(): Observable<Action>;
}

class EffectsRunner implements OnDestroy {
  get isStarted(): boolean;
  start(): void;
  ngOnDestroy(): void;
}

interface OnDestroy {
  ngOnDestroy(): void;
}

interface ObservableNotification<T> {
  kind: 'N' | 'E' | 'C';
  value?: T;
  error?: any;
}

type EffectPropertyKey<T extends Record<keyof T, Object>> = Exclude<
  keyof T,
  keyof Object
>;

interface EffectMetadata<T extends Record<keyof T, Object>>
  extends Required<EffectConfig> {
  propertyName: EffectPropertyKey<T>;
}

type EffectsMetadata<T extends Record<keyof T, Object>> = {
  [Key in EffectPropertyKey<T>]?: EffectConfig;
};

interface Type<T = any> {
  new (...args: any[]): T;
}

interface ModuleWithProviders<T> {
  ngModule: Type<T>;
  providers?: any[];
}

interface EnvironmentProviders {
  ɵproviders: any[];
}

interface FactoryProvider {
  provide: any;
  useFactory: (...args: any[]) => any;
  deps?: any[];
}

interface InjectionToken<T> {
  toString(): string;
}

interface Observable<T> {
  pipe(...operations: any[]): Observable<any>;
  subscribe(...args: any[]): any;
}

interface OperatorFunction<T, R> {
  (source: Observable<T>): Observable<R>;
}

interface Operator<T, R> {
  call(subscriber: any, source: Observable<T>): any;
}

Constants and Tokens

const ROOT_EFFECTS_INIT: "@ngrx/effects/init";

function rootEffectsInit(): Action;

const EFFECTS_ERROR_HANDLER: InjectionToken<EffectsErrorHandler>;
const USER_PROVIDED_EFFECTS: InjectionToken<Array<Type<unknown> | InjectionToken<unknown>>[]>;
const _ROOT_EFFECTS_GUARD: InjectionToken<void>;
const _ROOT_EFFECTS: InjectionToken<[Array<Type<unknown> | Record<string, FunctionalEffect>>]>;
const _ROOT_EFFECTS_INSTANCES: InjectionToken<unknown[]>;
const _FEATURE_EFFECTS: InjectionToken<Array<Type<unknown> | Record<string, FunctionalEffect>>[]>;
const _FEATURE_EFFECTS_INSTANCE_GROUPS: InjectionToken<unknown[][]>;