I am new to angular + ngrx and have a question about proper control flow at scale. Suppose I have a Cars
component that can can load a list of cars and can create a new car. Once those effects execute, they'll dispatch SUCCESS
and FAILURE
actions. In my ngOnInit
, I am subscribing to each of those success/failure actions to perform appropriate - something like:
ngOnInit() {
this.actions$
.pipe(
ofType<fromCarsActions.GetCarsSuccessAction>(fromCarsActions.CarsActionTypes.GET_CARS_SUCCESS),
takeUntil(this.unsubscribe$)
)
.subscribe(results => {
// do something if load all cars SUCCEEDS
});
this.actions$
.pipe(
ofType<fromCarsActions.GetCarsFailureAction>(fromCarsActions.CarsActionTypes.GET_CARS_FAILURE),
takeUntil(this.unsubscribe$)
)
.subscribe(results => {
// do something if load all cars FAILS
});
this.actions$
.pipe(
ofType<fromCarsActions.AddCarSuccessAction>(fromCarsActions.CarsActionTypes.ADD_CAR_SUCCESS),
takeUntil(this.unsubscribe$)
)
.subscribe(results => {
// do something if add car SUCCEEDS
});
this.actions$
.pipe(
ofType<fromCarsActions.AddCarsFailureAction>(fromCarsActions.CarsActionTypes.ADD_CAR_FAILURE),
takeUntil(this.unsubscribe$)
)
.subscribe(results => {
// do something if add car FAILS
});
}
Subscribing to all these SUCCESS/FAILURE actions is fine if there's only a few, but can easily get out of hand very quickly for more complex components.
Another option I could do is dispatch the appropriate action in the effect itself, but that would not make the effect very reusable.
So my question is what's the best practice for a component that uses NGRX to communicate with the backend to easily manage subscribing to / listening to multiple different effect success/failures?
I understand this is a bit of an abstract question so please let me know if I can clarify anything.
you trigger the Action
Action will trigger a Reducer( will update the store only) or Effect(handles the service- responsible to fetch data from DB)
then you can subscribe to the Selector to get the change.
In your case create Action -
export const loadCars = createAction('Load Car data');
export const getcarsSuccess = createAction('Get Car data Success', props<{ carData: any }>());
export const getCarsError = createAction('Get Car data Error', props<{ errorResponse: any}>());
export const createCars = createAction('Add Car data');
export const createCarsSuccess = createAction('Add Car data Success', props<{ carData: any }>());
export const createCarsError = createAction('Add Car data Error', props<{ errorResponse: any}>());
the above action can trigger a effect or reducer
In Effect:
@Effect()
public loadCarData$ = createEffect(() => this.actions$.pipe(
ofType(actions.loadCars ) ...
In Reducer:
const initReducer = createReducer(
initialIState,
on(actiona.loadCarData, state => (state)))
In selector:
export const carDataLoaded = (state: fromReducer.carData) => state.carData ;
export const getCarData = createSelector(
getInitState,
carDataLoaded
);
Finally In the component:
You can subscribe to selector getCarData, so component - action - effect- reducer - selector - component
In Comp
private carStore: Store<carStore>
this.carStore.dispatch(new loadCars ()); //dispatch load Cars Action
this.carStore.pipe(select(
getCarData })
).subscribe(cars => console.log(cars)) // subscribe to selector
Note: You can subscribe to any action directly from component as you have mentioned but that will not serve the purpose of using NGRX State Management.
Update NGRX Store From anywhere in Angular App and Access the store data from anywhere you want in the app. Without worrying about maintaining the state of data.