0
0
Angularframework~5 mins

Effects for side effects in Angular

Choose your learning style9 modes available
Introduction

Effects help you run extra code when something happens in your app, like loading data or saving info. They keep your app organized by handling these side tasks outside your main code.

When you want to fetch data from a server after a user clicks a button.
When you need to save user input to a database without blocking the app.
When you want to show a message after an action completes successfully.
When you need to log user actions for analytics without mixing it with UI code.
When you need to handle errors from server calls and show alerts.
Syntax
Angular
import { createEffect, ofType, Actions } from '@ngrx/effects';
import { Injectable } from '@angular/core';
import { map, mergeMap, catchError } from 'rxjs/operators';
import { of } from 'rxjs';

@Injectable()
export class MyEffects {
  myEffect$ = createEffect(() =>
    this.actions$.pipe(
      ofType('ACTION_TYPE'),
      mergeMap(() =>
        someServiceCall().pipe(
          map(data => ({ type: 'SUCCESS_ACTION', payload: data })),
          catchError(() => of({ type: 'FAILURE_ACTION' }))
        )
      )
    )
  );

  constructor(private actions$: Actions) {}
}

createEffect defines a side effect that listens to actions and can dispatch new actions.

ofType filters actions by their type so the effect reacts only to specific actions.

Examples
This effect listens for 'LOAD_DATA' action, calls an API, and dispatches success or failure actions.
Angular
myEffect$ = createEffect(() =>
  this.actions$.pipe(
    ofType('LOAD_DATA'),
    mergeMap(() => fetchDataFromApi().pipe(
      map(data => ({ type: 'LOAD_DATA_SUCCESS', payload: data })),
      catchError(() => of({ type: 'LOAD_DATA_FAILURE' }))
    ))
  )
);
This effect logs the user click action and dispatches a new action 'LOGGED_CLICK'.
Angular
logEffect$ = createEffect(() =>
  this.actions$.pipe(
    ofType('USER_CLICK'),
    map(action => {
      console.log('User clicked:', action);
      return { type: 'LOGGED_CLICK' };
    })
  )
);
This effect shows an alert but does not dispatch any new action (dispatch: false).
Angular
noDispatchEffect$ = createEffect(() =>
  this.actions$.pipe(
    ofType('SHOW_ALERT'),
    map(() => {
      alert('Alert shown!');
    })
  ), { dispatch: false }
);
Sample Program

This example shows an effect that listens for 'LOAD_FRUITS' action, fetches fruit data, and dispatches a success action with the fruit list.

Angular
import { Injectable } from '@angular/core';
import { createEffect, ofType, Actions } from '@ngrx/effects';
import { map, mergeMap, catchError } from 'rxjs/operators';
import { of } from 'rxjs';

// Simulated service that returns data
function fetchDataFromApi() {
  return of(['apple', 'banana', 'cherry']);
}

@Injectable()
export class FruitEffects {
  loadFruits$ = createEffect(() =>
    this.actions$.pipe(
      ofType('LOAD_FRUITS'),
      mergeMap(() =>
        fetchDataFromApi().pipe(
          map(fruits => ({ type: 'LOAD_FRUITS_SUCCESS', payload: fruits })),
          catchError(() => of({ type: 'LOAD_FRUITS_FAILURE' }))
        )
      )
    )
  );

  constructor(private actions$: Actions) {}
}

const actions$ = of({ type: 'LOAD_FRUITS' });
const effects = new FruitEffects(actions$);
effects.loadFruits$.subscribe(action => console.log(JSON.stringify(action)));
OutputSuccess
Important Notes

Effects run outside your components to keep UI code clean and focused.

Always handle errors in effects to avoid app crashes.

Use dispatch: false if your effect does not send new actions.

Summary

Effects handle side tasks like data loading or logging outside components.

They listen for actions and can dispatch new actions based on results.

Use effects to keep your app organized and responsive.