I have an Angular app with multiple pages (e.g. toy page, vegetable page, drink page) that all look the same and consist almost entirely of one table.
The table data is managed via NgRx (loading, saving, sorting, filtering) and each page has its own feature state. At the moment all code parts (actions/reducers/selectors/effects) are copied for each page.
Since all pages behave almost the same, I want to use a default implementation with a generic behavior/workflow and adopt it for specific pages (if needed).
Does anyone have any ideas on how I can implement this using NgRx or another Redux library?
Part of the current NgRx implementation used for each page:
// src/app/toy.model.ts
export interface Toy { id: number; name: string; price: number; }
// src/app/store/toy.actions.ts
export const loadToys = createAction('[Toy] Load Toys');
export const loadToysSuccess = createAction('[Toy] Load Toys Success', props<{ toys: Toy[] }>());
export const loadToysFailure = createAction('[Toy] Load Toys Failure', props<{ error: string }>() );
// src/app/store/toy.reducer.ts
export interface ToyState { toys: Toy[]; error: string;}
export const initialState: ToyState = { toys: [], error: '' };
export const toyReducer = createReducer(
initialState,
on(loadToys, state => ({ ...state, error: '' })),
on(loadToysSuccess, (state, { toys }) => ({...state, toys })),
on(loadToysFailure, (state, { error }) => ({...state, error }))
);
// src/app/store/toy.selectors.ts
export const selectToyState = createFeatureSelector<ToyState>('toys');
export const selectAllToys = createSelector(selectToyState, (state: ToyState) => state.toys);
export const selectToyError = createSelector(selectToyState, (state: ToyState) => state.error);
// src/app/store/toy.effects.ts
export class ToyEffects {
loadToys$ = createEffect(() =>
this.actions$.pipe(
ofType(loadToys),
mergeMap(() =>
this.toyService.getAll().pipe(
map(toys => loadToysSuccess({ toys })),
catchError(error => of(loadToysFailure({ error })))
)))); }
This seems to me to be similar to the GoF template method pattern, but I suspect I can’t use it.
bruno is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.