0
0
AngularConceptBeginner · 3 min read

What is Effect in NgRx: Explanation and Example

In NgRx, an Effect is a way to handle side effects like API calls or asynchronous tasks outside of components and reducers. It listens for specific actions and performs tasks, then dispatches new actions with results to update the state.
⚙️

How It Works

Think of an Effect as a helper that watches for certain signals (actions) in your app. When it sees a signal, it does some work like fetching data from a server or saving something, then sends back a new signal with the result.

This keeps your app organized by separating the side tasks from the main logic that changes the state. It’s like having a friend who handles errands for you when you ask, so you can focus on other things.

💻

Example

This example shows an Effect that listens for a loadItems action, calls a fake API service to get items, and then dispatches a loadItemsSuccess action with the data.

typescript
import { Injectable } from '@angular/core';
import { createEffect, ofType, Actions } from '@ngrx/effects';
import { of } from 'rxjs';
import { catchError, map, mergeMap } from 'rxjs/operators';
import * as ItemActions from './item.actions';
import { ItemService } from './item.service';

@Injectable()
export class ItemEffects {
  loadItems$ = createEffect(() =>
    this.actions$.pipe(
      ofType(ItemActions.loadItems),
      mergeMap(() =>
        this.itemService.getItems().pipe(
          map(items => ItemActions.loadItemsSuccess({ items })),
          catchError(() => of(ItemActions.loadItemsFailure()))
        )
      )
    )
  );

  constructor(private actions$: Actions, private itemService: ItemService) {}
}

// item.actions.ts
import { createAction, props } from '@ngrx/store';

export const loadItems = createAction('[Item] Load Items');
export const loadItemsSuccess = createAction(
  '[Item] Load Items Success',
  props<{ items: string[] }>()
);
export const loadItemsFailure = createAction('[Item] Load Items Failure');

// item.service.ts
export class ItemService {
  getItems() {
    return of(['Apple', 'Banana', 'Cherry']); // Simulated API call
  }
}
Output
When the loadItems action is dispatched, the effect calls getItems(), then dispatches loadItemsSuccess with ['Apple', 'Banana', 'Cherry'].
🎯

When to Use

Use Effects when you need to do tasks that don't directly change the state but affect it later, like:

  • Fetching or saving data from a server
  • Calling external APIs
  • Performing asynchronous operations
  • Triggering multiple actions based on one event

This keeps your state management clean and your components simple, focusing only on displaying data and user interaction.

Key Points

  • Effects listen for actions and perform side effects.
  • They keep side tasks separate from state changes.
  • Use RxJS operators to handle async work inside effects.
  • Effects dispatch new actions with results to update the store.
  • They help keep components and reducers simple and focused.

Key Takeaways

Effects handle side effects like API calls outside reducers and components.
They listen for actions and dispatch new actions with results.
Use effects to keep your state logic clean and separate from async tasks.
Effects use RxJS to manage asynchronous operations smoothly.
They improve app organization by separating concerns clearly.