import { switchMap, filter, catchError } from 'rxjs/operators'; import { ActionsObservable, combineEpics, Epic } from 'redux-observable'; import { Actions, fetchProductListAsync, fetchCartedProductListAsync, fetchCouponListAsync, fetchCartedProductListEditAsync, fetchPaymentCartedProductListAsync, } from 'reducers/actions'; import { isActionOf } from 'typesafe-actions'; import { of } from 'rxjs'; import { Service } from 'index'; /** * @description 제품 목록을 가져오는 에픽 */ const fetchProductListEpic: Epic = ( action$: ActionsObservable<Actions>, _, { productService }: Service, ) => action$.pipe( filter(isActionOf(fetchProductListAsync.request)), switchMap(({ payload }) => { const { items, totalProducts } = productService.getItems( payload.currentPage, ); return of(fetchProductListAsync.success({ items, totalProducts })); }), catchError(err => { return of(fetchProductListAsync.failure(err)); }), ); /** * @description 카트 목록 가져오기 */ const fetchCartedProductListEpic: Epic = ( action$: ActionsObservable<Actions>, _, { productService }: Service, ) => action$.pipe( filter(isActionOf(fetchCartedProductListAsync.request)), switchMap(({ payload }) => { if (payload.productIdList) { const { items } = productService.getCartedItems(payload.productIdList); return of( fetchCartedProductListAsync.success({ items }), fetchCouponListAsync.request(), ); } return of(fetchCartedProductListAsync.success({ items: [] })); }), catchError(err => { return of(fetchCartedProductListAsync.failure(err)); }), ); /** * @description 카트 수정오기 */ const fetchCartedProductListEditEpic: Epic = ( action$: ActionsObservable<Actions>, _, { productService }: Service, ) => action$.pipe( filter(isActionOf(fetchCartedProductListEditAsync.request)), switchMap(({ payload }) => { const { item, quantity } = productService.getCartedItem( payload.id, payload.quantity, ); if (item) { return of(fetchCartedProductListEditAsync.success({ item, quantity })); } return of(fetchCartedProductListEditAsync.failure('cart edit error')); }), catchError(err => { return of(fetchCartedProductListEditAsync.failure(err)); }), ); /** * @description 카트에서 선택된 목록만 */ const fetchPaymentCartedProductListEpic: Epic = ( action$: ActionsObservable<Actions>, _, {}: Service, ) => action$.pipe( filter(isActionOf(fetchPaymentCartedProductListAsync.request)), switchMap(({ payload }) => { if (payload.ProductModelList) { return of( fetchPaymentCartedProductListAsync.success({ item: payload.ProductModelList, }), ); } return of( fetchPaymentCartedProductListAsync.success({ item: [], id: payload.id, }), ); }), catchError(err => { return of(fetchPaymentCartedProductListAsync.failure(err)); }), ); /** * @description 쿠폰 목록 가져오기 */ const fetchCouponListEpic: Epic = ( action$: ActionsObservable<Actions>, _, { productService }: Service, ) => action$.pipe( filter(isActionOf(fetchCouponListAsync.request)), switchMap(() => of(productService.getCoupons()).pipe( switchMap(payload => { return of(fetchCouponListAsync.success({ data: payload })); }), ), ), catchError(err => { return of(fetchCouponListAsync.failure(err)); }), ); export const rootEpic = combineEpics( fetchProductListEpic, fetchCartedProductListEpic, fetchCouponListEpic, fetchCartedProductListEditEpic, fetchPaymentCartedProductListEpic, );