you have:
- a component where you need your list
- a service where you do http requests
- a state, ngrx
steps:
a) from the component, dispatch an action - to get the list
b) in component, listen to the listAction (to receive new data)
ngOnInit() {
this.store.dispatch(getListAction); // this will fire the action
this.store.pipe(
select(fromStore.selectList)
).subscribe(yourList => {
// here you have the list
});
}
actions.ts
export enum Types {
GET_LIST = '[Store Type] Get List',
GET_LIST_SUCCESS = '[Store Type] Get List Success',
GET_LIST_FAILED = '[Store Type] Get List Failed',
}
export const getListAction = createAction(
Types.GET_LIST // this will be fired from component, and will fire the store effect
);
export const getListSuccessAction = createAction(
Types.GET_LIST_SUCCESS, // this will be fired when service return the list
props<{list: obj_type[]}>
);
export const getListSuccessAction = createAction(
Types.GET_LIST_FAILED, // this will be fired when service throws error
props<{msg: string}>
);
effects.ts
@Injectable()
export class MyEffects {
constructor(service: YourService) {
}
getList$ = createEffect(() =>
this.actions$.pipe(
ofType(getListAction),
switchMap(() =>
this.your_service.getList().pipe(
tap((list) => getListSuccessAction({list})),
catchError((error) =>
of(getListFailedAction({ msg: error.message }))
)
)
)
)
);
}
reducer.ts
export const reducer = createReducer(
initialState,
on(getListAction, (state) => ({
...state,
request: PENDING
})),
on(getListSuccessAction, (state, { list}) => ({
// your component store.pipe(select) will be fired with data from here
...state,
list:
request: COMPLETED
})),
on(getListFailedAction, (state, { msg }) => ({
...state,
error: {msg},
request: FAILED
}))
);````
selectors.ts
export const selectState = (state: AppState) => state;
export const selectList =
createSelector(selectState , (state) =>
state.list);
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…