Angular

Angular - ngrx in State (2) Effects

인어공쭈 2023. 3. 8. 14:16

주요 개념

  • 효과는 구성 요소에서 부작용을 분리하여 상태를 선택하고 작업을 발송
  • RxJS를 기반으로 구현되어 있으며, Observable을 반환한다
  • Effects는 Store 에서 발송된 모든 작업 의 ​​observable을 수신 서비스
  • 동기식 또는 비동기식 작업을 수행하고 새 작업을 반환
import { Injectable } from '@angular/core';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { EMPTY } from 'rxjs';
import { map, exhaustMap, catchError } from 'rxjs/operators';
import { MoviesService } from './movies.service';

@Injectable()
export class MovieEffects {

  loadMovies$ = createEffect(() => this.actions$.pipe(
    ofType('[Movies Page] Load Movies'),
    exhaustMap(() => this.moviesService.getAll()
      .pipe(
        map(movies => ({ type: '[Movies API] Movies Loaded Success', payload: movies })),
        catchError(() => EMPTY)
      ))
    )
  );

  constructor(
    private actions$: Actions,
    private moviesService: MoviesService
  ) {}
}

 

Effect Metadata

- Effect이 다른 작업을 전달하지 않으면 효과가 정확히 동일한 작업을 '구독'하고 '전달'하기 때문에 브라우저가 충돌하여 무한 루프가 발생한다. 이를 방지하려면 두 번째 인수로 함수 { dispatch: false } 추가

import { Injectable } from '@angular/core';
import { Actions, createEffect } from '@ngrx/effects';
import { tap } from 'rxjs/operators';

@Injectable()
export class LogEffects {
  constructor(private actions$: Actions) {}
  
  logActions$ = createEffect(() =>
    this.actions$.pipe(
      tap(action => console.log(action))
    ), { dispatch: false });
}

 

Resubscribe on Error

- 자동으로 다시 구독되므로 발송된 모든 작업을 계속 수신한다.

- 재구독을 비활성화하려면 메타데이터 에 추가해야한다. 

import { Injectable } from '@angular/core';
import { Actions, ofType, createEffect } from '@ngrx/effects';
import { of } from 'rxjs';
import { catchError, exhaustMap, map } from 'rxjs/operators';
import {
  LoginPageActions,
  AuthApiActions,
} from '../actions';
import { AuthService } from '../services/auth.service';

@Injectable()
export class AuthEffects {
  logins$ = createEffect(
    () =>
      this.actions$.pipe(
        ofType(LoginPageActions.login),
        exhaustMap(action =>
          this.authService.login(action.credentials).pipe(
            map(user => AuthApiActions.loginSuccess({ user })),
            catchError(error => of(AuthApiActions.loginFailure({ error })))
          )
        )
        // Errors are handled and it is safe to disable resubscription
      ),
    { useEffectsErrorHandler: false }
  );

  constructor(
    private actions$: Actions,
    private authService: AuthService
  ) {}
}
반응형

'Angular' 카테고리의 다른 글

Angular - 타입스크립트의 장점  (0) 2023.03.20
Angular 란?  (0) 2023.03.14
Angular - NgRx란?  (0) 2023.03.08
Angular - ngrx in State (3) router-store&Entity& component-store  (0) 2023.03.08
Angular - ngrx in State (1) Store  (0) 2023.03.07