Start Implementation:

Clean up the existing NgRx code:

Change module imports in app.module

to StoreModule.forRoot({}) to EffectsModule.forRoot([])

Remove app.effects and the reducers folder

2. Add a progress bar module where we implement our progress bar infrastructure.

ng g m progress

3. NgRx preparation.

Create a folder called store in app/progress

in Create 5 files:

progress.actions.ts

progress.effects.ts

progress.reducer.ts

progress.selectors.ts

progress.state.ts

Implement the progress bar store model

We need to keep track of every progress bar in the app, which is why we should remember every progress bar’s state (whether we should show it or not).

The most suitable structure for this purpose is a simple object, where a key will be the id and the value is a boolean value that indicates the current state.

Add a new interface to progress.state.ts :

export interface ProgressState {

progresses: { [id: string]: boolean }; }

Implement progress bar actions

To allow the progress bars to ‘show’ or ‘hide’, we need to add two actions: Show and Hide .

I will omit all imports, but you can find the whole application on GitHub repo.

Let’s start with types:

export enum ProgressActionTypes {

SHOW = '[Progress] Show',

HIDE = '[Progress] Hide'

}

Add new actions:

It’s worth noting that we have id as a constructor parameter. This is because we need to indicate which progress bar needs to be updated.

Implement progress bar reducer

It’s pretty simple, but don’t forget that our default state is just an empty object. We will fill it out afterwards.

Selectors

First, create a function to extract progressState from the application state.

const selectProgressState = (state: AppState) => state.progressState;

Let’s create a selector. We use props to retrieve the state for the given progressId .

export const showProgress = () => {

return createSelector(selectProgressState, (state, props) => state.progresses[props.progressId]);

};

Effects

Effects are the most important thing here because they are the method of how we dispatch our actions. Let’s assume that we have different actions, but only some of them are the cause of showing and hiding the progress bar.

Let’s create some mock actions.

Create app.actions.ts.

I won’t list all constructor params, as I will only use these actions for testing purposes.

Go back to the effects.

Let’s introduce an object to store all progress bar triggers.

The key in this object will be progressId , and the value will be object . It consists of what can trigger the showing, and what can trigger the hiding of the progress bar.

Here is the outcome:

You can see that we have one progress bar login_progress that can only be shown when the login occurs, and can only be hidden after login was successful, or failed.

This structure can be convenient for the user to store and track each progress bar, but it is not as good to use in effects.

We need to prepare it for use in effects by converting two collections. SHOW_ACTIONS and HIDE_ACTIONS where the key is an action and the value is a progress bar id.

It will be more suitable for use in ofType lettable operator of the actions$ chain.

Let’s convert PROGRESS_ACTIONS to these two objects:

So we’re about to finish our effects. But, we’ve forgotten the main thing — effects themselves.

Finally, for NgRx infrastructure, we need to add progressStore as a store feature.

StoreModule.forFeature('progressState', progressReducer),

EffectsModule.forFeature([ProgressEffects])