Blog: https://indepth.dev/posts/120…

an action is a constituent of a reducer, as well as of an effect. NgRx ensures that actions are first handled by the reducers, after which they will eventually be intercepted by the effects.

Actions are part of a Reducer and part of an Effect. NgRx ensures that operations are first handled by reducers, and then they are eventually intercepted by effects.

The Reducer handles the action, which is then resolved by effect.

Providing the effects

ForRoot and forFeature receive input parameters that are exported classes of other.ts files, rather than concrete class instances. Obtain metadata according to class.

EffectsModule. ForRoot can only be called once, because this method also instantiates other NGRX important services, such as effectsRunner and effectSources.

The example in Spartacus does not use the forRoot method.

The effects input parameter is an array:

These are all concrete effect implementations:

Once the effects (classes) are registered, in order to set them up, an observable will be created (with the help of EffectSources) and subscribed to (thanks to EffectRunner);

  • reducer: the shape of application
  • state entity: where the app information is kept, also where the place actions meet reducers, meaning it’s where reducers being invoked, which may cause state changes

State is the model layer, while the Store is the middleware between the consumer and the State.

State is where the application stores data.

  • the Store entity – the middleman between the data consumer(e.g: a smart component) and the model(the State entity)

A Store is an intermediate layer between data consumers, such as Angular Component and Model (that is, State Entity).

The effects will be the merge.

all the effects(e.g: those created by createEffect for example) will be merged into one single observable whose emitted values will be actions.

The Effects are merged into an Observable, which emits an Actions value.

Store is also an Observer of stream:

Effect -- -- -- -- > actions | - be store intercept

actions$

AC means a type: extends ActionCreator< String, Creator>

V = Action; if not specified, the default type is Action:

  • ScannedActionsSubject: comes from @ngrx/store and it is a Subject(thus, an Observable) that emits whenever actions are dispatched, but only after the state changes have been handled.

So, when an action is dispatched(Store.dispatch()), the State entity will first update the application state depending on that action and the current state with the help of the reducers, then it will push that action into an actions stream, created by ScannedActionsSubject.

After the Store Dispatch, first the state machine is migrated and the application state changes, which are driven by the Reducer. Then push the action stream to the action stream.

By setting the Actions’ source to ScannedActionsSubject, every time we have something like this.actions$.pipe().subscribe(observer) the observer will be part of ScannedActionsSubject’s observers list, meaning that when the subject emits an action(e.g: subject.next(action)), all the registered observers will receive it. This should explain why all the effects will receive the same actions, But, with ofType’s help, these can be filtered out – ofType

OfType

In order to determine which actions should trigger which effects, the OfType custom operator is used.

Maintain the mapping between action and effect.

RxJS filter Operator is also used internally for ofType:

Look at the implementation of Observable. Pipe:

export class Observable<T> implements Subscribable<T> {
  /* ... */
  
  pipe<A, B>(op1: OperatorFunction<T, A>, op2: OperatorFunction<A, B>): Observable<B>;
  
  /* ... */
}

where OperatorFunction<T,A> specifies the type of a function that receives an observable as a parameter and returns another observable:

OperatorFunction: Receive two type parameters, T representing the type of the original Observable package and A representing the type contained in the new Observable returned.

It returns a new Observable of type B.

Store.dispatch(event)

It signals that an event that requires state changes is sent from the UI(e.g a smart component).

Store.dispatch() will push the action(event) into an actions stream(which is different from the one that belongs to the effects):

Action

Dispatch via UI/Service/Effects.

Creator<P, R> is simply a function takes up a parameter of type P and returns an object of type R.

reducer

Reducers are pure functions that are responsible for state changes.

Interface definition of reducer:

export interface ActionReducer<T, V extends Action = Action> {
  (state: T | undefined, action: V): T;
}

This syntax defines an interface that describes a function type, with the definition of the function type in curly braces and the definition of the input interface to the function. The function takes two input parameters, state and action. The types are T(undefined is also acceptable) and V, followed by a colon after the braces, which defines that the return parameter should also be of type T.

Clearly, this function is a state machine that returns a new state based on the current state and input actions.

The way TypeScript describes a function’s signature by defining an interface is very different from the way it is in ABAP.

Take the reducer in address-verification. Reducer. TS as an example: How is this reducer setup?

In index.ts, we separate these reducers with the same name by importing * as:

The unified return via getReducers is:

Provider information is provided via the ReducerToken and GetReducers:

Providers use the metadata provided by @NgModule:

Store

It doesn’t store data, it’s just middleware.

The source code:

export class Store<T> extends Observable<T> implements Observer<Action> {
  constructor(
    state$: StateObservable,
    private actionsObserver: ActionsSubject,
    private reducerManager: ReducerManager
  ) {
    super();

    this.source = state$;
  }
  
  /* ... */
}

The Store accepts data from the outside world, which is state$.

Every time the source (state$) emits, the Store class will send the value to its subscribers.

Allows consumer ↔ ️ state communication ⬆ ️ | | -- -- -- -- -- -- -- -- -- -- -- newState because -- -- -- -- -- -- -- -- -- -- - | | < -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - | | | | Store. The source = $state | | | | | | < -- storing data | Store | Action | state | | | -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - > | | | | Store. The dispatch () | | -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - | ⬆ ️ Action | | newState because | | ⬇ ️ | -- -- -- -- -- -- -- -- -- -- -- -- - | | | Reducer | < -- -- The state changes | | -- -- -- -- -- -- -- -- -- -- -- -- --

More of Jerry’s original articles can be found on “Wang Zixi “: