• Jobs
  • About Us
  • professionals
    • Home
    • Jobs
    • Courses and challenges
  • business
    • Home
    • Post vacancy
    • Our process
    • Pricing
    • Assessments
    • Payroll
    • Blog
    • Sales
    • Salary Calculator

0

681
Views
Angular NGRX: use withLatestFrom para llamar a la API solo una vez. Sin embargo, 'cargador' todavía se establece en verdadero

Creé el siguiente código, tratando de asegurarme de que no se vuelva a llamar a la API cuando se establece el estado, y de evitar el uso de suscripciones en el componente.

 loadPackingList$ = createEffect(() => { return this.actions$.pipe( ofType(PackingPageActions.loadPackingList), switchMap((action) => of(action).pipe( withLatestFrom(this.store.select(selectPackingList)), filter(([action, list]) => !list || list.length === 0), switchMap(([action, latest]) => this.packingService.getPackingList(action.request).pipe( map((list) => PackingApiActions.loadPackingListSuccess({ list })), catchError((errors) => of(PackingApiActions.loadPackingListFail({ errors })) ) ) ) ) ) ); });

Esto funciona más o menos (la API no se vuelve a llamar) y se basa, entre otros, en: Cómo enviar una solicitud al servidor solo una vez usando @NgRx/effects

Sin embargo, la propiedad de carga aún se establece en verdadero nuevamente, lo que no debería suceder:

 export const packingReducer = createReducer( initialState, on(PackingPageActions.loadPackingList, (state) => ({ ...state, loading: true, })),

OnInit del componente:

 this.store.dispatch( PackingPageActions.loadPackingList({ request: this.PACKING_REQUEST }) );

¿Alguien tiene una idea de cómo solucionar esto?

¡Gracias!

about 3 years ago · Santiago Trujillo
1 answers
Answer question

0

primero puedes limpiar un poco la transmisión:

 loadPackingList$ = createEffect(() => { return this.actions$.pipe( ofType(PackingPageActions.loadPackingList), withLatestFrom(this.store.select(selectPackingList)), filter(([action, list]) => !list || list.length === 0), switchMap(([action, latest]) => this.packingService.getPackingList(action.request).pipe( map((list) => PackingApiActions.loadPackingListSuccess({ list })), catchError((errors) => of(PackingApiActions.loadPackingListFail({ errors })) ) ) ) ); });

no necesita el switchMap externo en of , simplemente redundante.

en segundo lugar, también deberá realizar una verificación similar en su reductor para asegurarse de que no se establezca a menos que el efecto realmente se vaya:

 export const packingReducer = createReducer( initialState, on(PackingPageActions.loadPackingList, (state) => ({ ...state, loading: !state.whatever.the.path.to.the.list.is?.length, })),

o en lugar de filtrar, simplemente puede simular respuestas con la lista ya obtenida:

 loadPackingList$ = createEffect(() => { return this.actions$.pipe( ofType(PackingPageActions.loadPackingList), withLatestFrom(this.store.select(selectPackingList)), switchMap(([action, latest]) => ((latest && latest.length) ? of(latest) : this.packingService.getPackingList(action.request)).pipe( map((list) => PackingApiActions.loadPackingListSuccess({ list })), catchError((errors) => of(PackingApiActions.loadPackingListFail({ errors })) ) ) ) ); });

podría hacer esto de otras maneras, como tener otra acción allí que indique que la solicitud realmente se está ejecutando, como la solicitud loadPackingListRequest que el efecto se emitirá justo antes de la solicitud para indicar que realmente está sucediendo, y esto es lo que establece el estado de loading en verdadero , probablemente más limpio de esta manera ya que no tiene una dependencia oculta en la sincronización del código entre su reductor y efectos. pero es preferencia en este punto.

EDITAR:

la tercera estrategia de acción se vería un poco así:

 loadPackingList$ = createEffect(() => { return this.actions$.pipe( ofType(PackingPageActions.loadPackingList), withLatestFrom(this.store.select(selectPackingList)), filter(([action, list]) => !list || list.length === 0), switchMap(([action, latest]) => from([ of(PackingApiActions.loadingPackingList()), this.packingService.getPackingList(action.request).pipe( map((list) => PackingApiActions.loadPackingListSuccess({ list })), catchError((errors) => of(PackingApiActions.loadPackingListFail({ errors })) ) ) ]).pipe(mergeAll())) ); });

de esta manera, su efecto emitirá dos acciones, una que indica que realmente está cargando y otra que indica si falló o tuvo éxito.

luego modifica el reductor para mirar la acción de carga en lugar de establecer la carga en verdadero:

 export const packingReducer = createReducer( initialState, on(PackingApiActions.loadingPackingList, (state) => ({ ...state, loading: true, })),
about 3 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Our process Sales
Legal
Terms and conditions Privacy policy
© 2025 PeakU Inc. All Rights Reserved.

Andres GPT

Recommend me some offers
I have an error