简体   繁体   中英

what is the correct way to call multiple services in one effect?

I would appreciate your advice in this case.

I need that after successful login, a second call is made to a service that gets data from a json file on the file system and places it in web storage. The logic that I use now is the following

Having this services

Login service:

@Injectable({
  providedIn: 'root',
})
export class LoginService {
  private readonly ENDPOINT = 'some-path';

  constructor(private readonly httpClient: HttpClient) {}

  login(credentials: CredentialsModel) {
    return this.httpClient.post<UserModel>(this.ENDPOINT, credentials);
  }
}

Product service

@Injectable({
  providedIn: 'root',
})
export class ProductService {
  private readonly endpoint = 'some-path';

  constructor(private readonly httpClient: HttpClient) {}

  findAll() {
    return this.httpClient.get<
      {
        id: string;
        code: string;
      }[]
    >('assets/data/products.json');
  }
}

And the following effect

@Injectable()
export class LoginEffects {
  login$ = createEffect(() =>
    this.actions$.pipe(
      ofType(login),
      exhaustMap((action) =>
        this.loginService
          .login({
            username: action.credentials.username,
            password: action.credentials.password,
          })
          .pipe(
            map((userModel) => {
              this.matSnackBar.open('some message');
              this.router.navigateByUrl('/admin/dashboard').then();

              return successfulLogin({ userModel });
            }),
            catchError(() => {
              this.matSnackBar.open(
                this.translateService.instant('shared.error-message')
              );

              return EMPTY;
            })
          )
      )
    )
  );

  constructor(
    private readonly translateService: TranslateService,
    private readonly productService: ProductService,
    private readonly loginService: LoginService,
    private readonly matSnackBar: MatSnackBar,
    private readonly actions$: Actions,
    private readonly router: Router
  ) {}
}

The call to the product service only requires storing the information in session storage

What is the correct way so that after completing the login in the context of exhaustMap, the method of another service is called and to be able to call at the end the action of having completed the login successfully with the information obtained in the first call?

While this works, it can make the effect hard to understand. Especially when more service calls are added.

I would prefer to split the effect into multiple effects.

Effect -> Dispatch Action

Effect 2 -> Listen to Action -> Make second service call -> Dispatch action

This makes it easier to understand, to move things arround, to share effects, and to test effects.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM