Skip to content

Instantly share code, notes, and snippets.

@zoitsa
Last active November 5, 2019 18:54
Show Gist options
  • Save zoitsa/4ed65ed170b36393fbbd3b1ae124e3ff to your computer and use it in GitHub Desktop.
Save zoitsa/4ed65ed170b36393fbbd3b1ae124e3ff to your computer and use it in GitHub Desktop.
Cross-platform Ngrx
import { Injectable } from '@angular/core';
import { Actions, ofType, createEffect } from '@ngrx/effects';
import { mapTo, tap, switchMap, map, mergeMap, catchError, withLatestFrom, filter } from 'rxjs/operators';
import { ApprovalActions } from '../actions';
import { ApiService } from '../../services/api.service';
import { errorHandler } from '../../error-handler';
import { Store, select } from '@ngrx/store';
import * as fromDashboard from '../reducers';
@Injectable()
export class ApprovalEffects {
getPending$ = createEffect(() =>
this.actions$.pipe(
ofType(ApprovalActions.getAllPendingApprovals),
switchMap(res =>
this.apiService.getAllPendingApprovals()
),
map((res: any) => ApprovalActions.getAllPendingApprovalsComplete({ approvals: res }))
)
);
getReviewed$ = createEffect(() =>
this.actions$.pipe(
ofType(ApprovalActions.getReviewedApprovals),
switchMap(res =>
this.apiService.getReviewedApprovals()
),
map((res: any) => ApprovalActions.getReviewedApprovalsComplete({ approvals: res }))
)
);
resetDisplay$ = createEffect(() =>
this.actions$.pipe(
ofType(ApprovalActions.verifyReports),
map(() => ApprovalActions.displaySnackbar({ display: false, reports: {} })),
)
);
verifyReports$ = createEffect(() =>
this.actions$.pipe(
ofType(ApprovalActions.verifyReports),
withLatestFrom(this.store$.pipe(select(fromDashboard.selectApproveIsEnabled))),
filter(([payload, enabled]) => enabled), // only approve if enabled is true to avoid sidedrawer swipe
map(([payload, enabled]) => payload),
switchMap(payload =>
this.apiService.verifyReports({
status: payload.status,
reports: [payload.reports.report.id]
}) // mapTo is carrying the payload over
.pipe(
mapTo(payload)
)
), // end switch map
mergeMap((payload) => [
ApprovalActions.verifyReportsComplete(),
ApprovalActions.updateReviewed({
reports: {
...payload.reports,
status: payload.status
}
}),
]
), // end merge map
catchError(errorHandler(ApprovalActions.verifyReportsError)),
) // end pipe
);
// verifyReportsComplete happened and dispatched updateReviewed to update the expenses pending & reviewed status on state
updateReports$ = createEffect(() =>
this.actions$.pipe(
ofType(
ApprovalActions.updateReviewed,
),
switchMap(res => [
ApprovalActions.removePendingExpense({ reports: res.reports }),
ApprovalActions.addReviewedExpense({ reports: res.reports }),
ApprovalActions.displaySnackbar({ display: true, reports: res.reports }),
])
),
);
undoVerifyReports$ = createEffect(() =>
this.actions$.pipe(
ofType(ApprovalActions.undoVerifyReports),
switchMap(payload =>
this.apiService.verifyReports({
status: payload.status,
reports: [payload.reports.report.id]
}) // mapTo is carrying the payload over
.pipe(
mapTo(payload)
)
), // end switch map
mergeMap((payload) => [
ApprovalActions.undoVerifyReportsComplete(),
ApprovalActions.undoUpdateReviewed({
reports: {
...payload.reports,
status: payload.status
}
})
]
), // end merge map
catchError(errorHandler(ApprovalActions.undoVerifyReportsError)),
) // end pipe
);
undoUpdateReports$ = createEffect(() =>
this.actions$.pipe(
ofType(
ApprovalActions.undoUpdateReviewed,
),
switchMap(res => [
ApprovalActions.removeReviewedExpense({ reports: res.reports }),
ApprovalActions.addPendingExpense({ reports: res.reports }),
])
),
);
getExpenseCounts$ = createEffect(() =>
this.actions$.pipe(
ofType(ApprovalActions.getExpenseCounts),
switchMap(() => this.apiService.getExpenseCounts()),
map(counts => ApprovalActions.getExpenseCountsComplete({ counts }))
)
);
constructor(
private actions$: Actions,
private apiService: ApiService,
private store$: Store<fromDashboard.State>
) { }
}
import { Injectable } from '@angular/core';
import { Actions, ofType, createEffect } from '@ngrx/effects';
import { switchMap, map } from 'rxjs/operators';
import { ApiService } from '../../services/api.service';
import { ApprovalActions } from '../actions';
import { BaseModalService } from '../components/base/base-modal/base-modal.service';
@Injectable()
export class ApprovalEffects {
get$ = createEffect(() =>
this.actions$.pipe(
ofType(ApprovalActions.get),
switchMap(res =>
this.apiService.getPendingApprovals(res.page, res.sort, res.filters)
),
map((res) => ApprovalActions.getComplete({ approvals: res }))
)
);
applyFilter$ = createEffect(() =>
this.actions$.pipe(
ofType(ApprovalActions.applyFilters),
switchMap(res =>
this.apiService.getPendingApprovals(res.page, res.sort, res.filters)
),
map((res) =>
ApprovalActions.applyFiltersComplete({ approvals: res })
)
)
);
getExpenseCounts$ = createEffect(() =>
this.actions$.pipe(
ofType(ApprovalActions.getExpenseCounts),
switchMap(res => this.apiService.getExpenseCounts()),
map(res => ApprovalActions.getExpenseCountsComplete({ counts: res }))
)
);
verifyReports$ = createEffect(() =>
this.actions$.pipe(
ofType(ApprovalActions.verifyReports),
switchMap(res =>
this.apiService.verifyReports({
status: res.status,
reports: res.reports
})
),
map(() => ApprovalActions.verifyReportsComplete())
)
);
delete$ = createEffect(() =>
this.actions$.pipe(
ofType(ApprovalActions.deleteExpenses),
map(res => ApprovalActions.deleteExpensesComplete())
)
);
constructor(
private actions$: Actions,
private apiService: ApiService,
private modalService: BaseModalService
) {}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment