es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cómo asegurarse de que una solicitud HTTP dentro de un efecto esté finalizada antes de continuar.

Tengo una pregunta sobre cómo asegurarme de que una llamada de solicitud HTTP se complete antes de continuar con las futuras líneas de código. Cuando despacho la acción:

this._appStore.dispatch(SomeActionHere({status: contactStatus, contactId: this.contactId}));

Quiero asegurarme de que la solicitud HTTP POST de la función someOtherService.update en el archivo de efectos haya finalizado antes de llamar a la función shouldBeCalledAfter de someService. Idealmente, quisiera hacer esto sin utilizar algún tipo de BehaviorSubject. Para aclarar, el efecto SomeActionHere se activa después de despachar la acción SomeActionHere.

onClick(selectedOption?: {displayName: string, value: LogCallSubmitOptionsEnum}) {
    const contactStatus$ = this.callLogStore.select(getContactStatus).pipe(take(1));
    ... 
    forkJoin([contactStatus$, ...])
      .subscribe(([contactStatus]) => {
        this._appStore.dispatch(SomeActionHere({status: contactStatus, contactId: this.contactId}));
        ... 

    this.someService.shouldBeCalledAfter(callLogInfo, authToken.userId, logCallAndComplete, undefined, this.contactId, this.isManualLog)
      .subscribe((res) => {
        ...
      }, err => {
        ...
      });
  });
}

Archivo de efectos:

someActionHereEffect$ = createEffect(() =>
    this.action$.pipe(
      ofType(SomeActionHere),
      mergeMap(({ id }) =>
        this.someOtherService.update(id).pipe(
          map((res) => {
            ...
          catchError((error: any) => {
           ...
          }
          )
        )
      )
    )
  );

¿Existe alguna forma de asegurarse de que una llamada de solicitud HTTP desde el archivo de efectos haya finalizado antes de pasar a la función someService.shouldBeCalledAfter?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Sí, puedes usar el operador switchMap en tu archivo de efectos para esperar a que la solicitud HTTP se complete antes de continuar con el siguiente observable en la cadena. Aquí está el código actualizado para tu archivo de efectos:

    someActionHereEffect$ = createEffect(() =>
      this.action$.pipe(
        ofType(SomeActionHere),
        switchMap(({ id }) =>
          this.someOtherService.update(id).pipe(
            map((res) => {
              // Tu lógica aquí
              return someOtherAction(); // devuelve otra acción si es necesario
            }),
            catchError((error: any) => {
              // Maneja el error aquí
              return of(someErrorAction()); // devuelve una acción de error si es necesario
            })
          )
        )
      )
    );
    

    Al usar switchMap, te estás desuscribiendo del observable previo (solicitud HTTP) y suscribiéndote al nuevo observable (respuesta de la solicitud HTTP) cada vez que se despacha una nueva acción del tipo SomeActionHere. Esto asegura que la solicitud HTTP se complete antes de que se ejecute el siguiente observable en la cadena (otra acción o efecto secundario).

    En tu código del componente, simplemente puedes eliminar el forkJoin y llamar directamente a la acción:

    onClick(selectedOption?: {displayName: string, value: LogCallSubmitOptionsEnum}) {
        const contactStatus$ = this.callLogStore.select(getContactStatus).pipe(take(1));
        // ... 
        contactStatus$.subscribe(contactStatus => {
            this._appStore.dispatch(SomeActionHere({status: contactStatus, contactId: this.contactId}));
        });
        // ...
        this.someService.shouldBeCalledAfter(callLogInfo, authToken.userId, logCallAndComplete, undefined, this.contactId, this.isManualLog)
            .subscribe((res) => {
                // ...
            }, err => {
                // ...
            });
    }
    

    Al despachar la acción, permites que los efectos manejen la solicitud HTTP y su respuesta, por lo que no necesitas esperar manualmente su finalización en el código de tu componente.

Comments are closed.