[Vidéo] Pourquoi les signaux sont la prochaine grande avancée pour Angular ?

Dans cette vidéo de 3 minute, découvrez pourquoi les signaux sont essentiels pour l'avenir du développement web et apprenez les 3 fonctions: signal / computed / effect

Skip to content

Comment utiliser les effect sur NgRx ?

Intérêt ?

Les effets de NgRx vous permettent de séparer les effets de côté-effets de votre application de votre logique de mise à jour de l'état. Cela peut être utile pour plusieurs raisons :

  • Séparation de la responsabilité : en séparant les effets de côté-effets de votre logique de mise à jour de l'état, vous pouvez mieux structurer votre code et rendre chaque partie de votre application plus facile à comprendre et à maintenir.
  • Testabilité : en séparant les effets de côté-effets de votre logique de mise à jour de l'état, vous pouvez les tester de manière plus facile et plus fiable. Vous pouvez également tester votre logique de mise à jour de l'état de manière plus facile en sachant que les effets de côté-effets ont été correctement gérés.
  • Performances : en exécutant les effets de côté-effets de manière asynchrone, vous pouvez éviter de bloquer le thread principal de votre application et améliorer les performances de votre application.

Installer

npm install @ngrx/effects

1. Rappel: les actions

Les actions sont des objets qui représentent des événements dans votre application. Ils sont émis par des composants ou d'autres parties de votre application et sont écoutés par des réducteurs pour mettre à jour l'état de votre application.

Voir le chapitre sur les actions pour plus de détails.

1. Créer l'effet de chargement des utilisateurs

Nous définissons un effet pour gérer le chargement des utilisateurs en réponse à l'action loadUsers. Cet effet écoute l'action loadUsers, fait appel au service UserService pour récupérer les utilisateurs, et émet les actions loadUsersSuccess ou loadUsersFailure en fonction du résultat.

typescript
import { inject } from '@angular/core';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { map, switchMap } from 'rxjs';
import { UserService } from '../../core/services/user.service';
import { usersActions } from './users.action';

// Créer un effet pour charger les utilisateurs
export const usersGetAll$ = createEffect(
  (actions$ = inject(Actions), userService = inject(UserService)) => {
    return actions$.pipe(
      ofType(usersActions.getAll),
      switchMap((action) => userService.getAll(action.sort)),
      map((users) => usersActions.getAllSuccess({ users }))
    );
  },
  { functional: true }
);
typescript
import { createActionGroup, emptyProps, props } from '@ngrx/store';
import { User } from './user';

export const usersActions = createActionGroup({
  source: 'Users',
  events: {
    'Get All':  emptyProps(), 
    'Get All Success': props<{ users: User[] }>(),
    'Get All Failure': props<{ error: any }>() 
  },
});
ts
export interface User {
    id: number;
    name: string;
    username?: string;
    email: string;
    address?: {
        street: string;
        suite: string;
        city: string;
        zipcode: string;
        geo: {
            lat: string;
            lng: string;
        }
    };
    phone?: string;
    website?: string;
    company?: {
        name: string;
        catchPhrase: string;
        bs: string;
    };
}
ts
import { HttpClient } from "@angular/common/http";
import { Injectable, inject } from "@angular/core";
import { Observable } from "rxjs";
import { User } from "./user";

@Injectable({
  providedIn: "root",
})
export class UserService {
  private http = inject(HttpClient);
  readonly url: string = "https://jsonplaceholder.typicode.com/users";

  getAll(): Observable<User[]> {
    return this.http.get<User[]>(this.url);
  }
}

actions$ est un flux d'actions provenant du store NgRx. Il s'agit d'un observable qui émet chaque action dispatchée dans l'application. En écoutant ce flux, on peut réagir à des actions spécifiques et déclencher des opérations asynchrones comme des requêtes HTTP.

Pourquoi cet enchaînement et ces opérateurs ?

  1. Filtrer les actions avec ofType
  • But : On utilise ofType pour filtrer les actions et ne réagir qu'à celles qui nous intéressent. Dans ce cas, nous filtrons les actions pour ne prendre que celles de type usersActions.getAll.
  • Pourquoi : Sans ofType, nous réagirions à toutes les actions dispatchées, ce qui n'est pas souhaitable. ofType garantit que notre effet ne se déclenche que pour les actions pertinentes.
  1. Effectuer une requête asynchrone avec switchMap
  • But : switchMap prend chaque action filtrée et effectue une opération asynchrone, ici une requête HTTP via userService.getAll.

mergeMap vs switchMap

Voir la différence entre mergeMap et switchMap dans le chapitre sur Comprendre très facilement la différence entre switchMap et mergeMap.

  1. Transformer la réponse avec map
  • But : map prend les résultats de la requête HTTP et les transforme en une nouvelle action usersActions.getAllSuccess avec les utilisateurs obtenus.
  • Pourquoi : En NgRx, après avoir effectué une opération asynchrone, on dispatch une nouvelle action pour mettre à jour l'état global de l'application. Cette nouvelle action contient les données nécessaires pour mettre à jour le store.

Ajoutez les effets dans la configuration

L'effet doit être ajouté à la configuration dans app.config.ts pour être utilisé dans l'application.

typescript
import { ApplicationConfig } from '@angular/core';
import { provideEffects } from '@ngrx/effects';
import { provideStore } from '@ngrx/store';
import { usersGetAll$ } from './store/users/users.effect';
import { usersReducer } from './store/users/users.reducer';

export const appConfig: ApplicationConfig = {
  providers: [
    provideStore({
      users: usersReducer
    }),
    provideEffects({
      usersGetAll$
    })
  ]
};

Les effets fonctionnels en NGRX permettent de gérer les opérations asynchrones et les effets secondaires de manière déclarative et concise. En utilisant createEffect avec des fonctions, nous simplifions la gestion des injections et rendons le code plus lisible et maintenable.

points à retenir

  • Les effets gèrent les opérations asynchrones et les effets secondaires.
  • Utilisez createEffect avec des fonctions pour créer des effets pures et injecter les dépendances.
  • Écoutez les actions pertinentes et émettez de nouvelles actions en fonction des résultats des opérations asynchrones.
  • Les effets doivent être ajoutés à la configuration du module NGRX.

bonnes pratiques

  • Gardez les effets simples et focus sur une seule responsabilité.
  • Gérer les erreurs de manière proactive avec des actions de type échec.
  • Utilisez des noms d'actions et d'effets descriptifs pour clarifier leur rôle.
  • Centralisez la logique d'effets dans des fichiers séparés pour une meilleure organisation.

En août, recevez en avant-première notre newsletter avec les dernières actualités, tutoriels, astuces et ressources Angular directement par email !