Как правильно заархитектурить экшен NGRX с двумя логическими шагами?

Для правильной архитектуры экшена NGRX с двумя логическими шагами, вам понадобятся два отдельных экшена и один эффект. Ниже приведена детальная инструкция по архитектуре экшена с двумя логическими шагами.

Шаг 1: Создание первого экшена
1. Создайте новый файл с именем first-action.ts.
2. В файле first-action.ts создайте константу для типа действия, например export const FIRST_ACTION = '[Feature] First Action'.
3. Создайте класс для первого экшена, который будет содержать свойство readonly type, инициализированное значением константы FIRST_ACTION, и необязательные свойства для передачи данных. Например:

export class FirstAction implements Action {
  readonly type = FIRST_ACTION;
  
  constructor(public payload?: any) {}
}

Шаг 2: Создание второго экшена
1. Создайте новый файл с именем second-action.ts.
2. В файле second-action.ts создайте константу для типа действия, например export const SECOND_ACTION = '[Feature] Second Action'.
3. Создайте класс для второго экшена, который будет содержать свойство readonly type, инициализированное значением константы SECOND_ACTION, и необязательные свойства для передачи данных. Например:

export class SecondAction implements Action {
  readonly type = SECOND_ACTION;
  
  constructor(public payload?: any) {}
}

Шаг 3: Создание эффекта
1. Создайте новый файл с именем your-effect.ts.
2. В файле your-effect.ts импортируйте необходимые классы и операторы из @ngrx/effects и файлы с экшенами.
3. Создайте класс для эффекта, который будет содержать инжектированный сервис, а также свойства firstAction$ и secondAction$ с помощью оператора ofType, а затем определите логику для обработки каждого экшена. Например:

import { Injectable } from '@angular/core';
import { Actions, Effect, ofType } from '@ngrx/effects';
import { mergeMap, map } from 'rxjs/operators';
import { YourService } from './your-service';
import { FIRST_ACTION, SecondAction } from './your-actions';

@Injectable()
export class YourEffect {
  constructor(private actions$: Actions, private yourService: YourService) {}

  @Effect()
  firstAction$ = this.actions$.pipe(
    ofType(FIRST_ACTION),
    mergeMap(() => this.yourService.doSomething().pipe(
      map(response => new SecondAction(response))
    ))
  );
}

Шаг 4: Зарегистрируйте эффект в вашем модуле
1. Откройте файл вашего модуля, в котором вы будете использовать эффект.
2. Импортируйте необходимые классы и провайдеры из @ngrx/effects.
3. В разделе providers вашего модуля добавьте провайдер для класса YourEffect. Например:

import { EffectsModule } from '@ngrx/effects';
import { YourEffect } from './your-effect';

@NgModule({
  imports: [
    ...,
    EffectsModule.forRoot([YourEffect])
  ],
  providers: [...], // добавьте ваш эффект в список провайдеров
  ...
})
export class YourModule { }

Теперь вы можете использовать эти экшены в ваших редюсерах и диспатчить их из ваших компонентов или сервисов с помощью store.dispatch().