A Complete Guide On Ngrx Store Architecture Using Angular

What is NgRx?

NgRx is a type of Angular framework for building reactive applications. NgRx provides picture perfect library support for:

  • Managing global and local state.
  • To promote a cleaner component architecture, it is an isolate of side effects.
  • Entity collection management.
  • Integration with the Angular Router.
  • When building many different types of applications, it uses Developer tooling that enhances developer experience.

Packages

NgRx packages are mainly divided into these categories

State

  • Store - RxJS used for global state management for Angular apps.
  • Effects - Side effect model for @ngrx/store.
  • Router Store - connect the Angular Router to @ngrx/store for Bindings.
  • Entity – To manage record collections, it will use Entity State adapter.
  • ComponentStore - Standalone library for managing local/component state.

Data

  • Data - Extension for simplified entity data management.

View

  • Component - Extension for fully reactive Angular applications.

Developer Tooling

  • Store Devtools - It enables visual tracking of state and time-travel debugging. It is Instrumentation for @ngrx/store.
  • Schematics - Angular applications using NgRx libraries is a Scaffolding library.

Let's see the following diagram which demonstrates the complete flow of a persistence EntityAction such as QUERY_ALL for the Hero entity type.

  • The NgRx data EntityReducer reads the action’s entityName property (Hero in this example). after that, it forwards the action and existing entity collection state to the EntityCollectionReducer for heroes.
  • The collection reducer picks a switch-case based on the action of the entityOp (operation) property. That case processes the action and collection state.it will be put into a new (updated) hero collection.
  • The store updates the entity cache in the state tree with that updated collection.
  • In the view, NgRx observable selectors detect and report the changes (if any) to subscribers.
  1. First of all, the view/component calls EntityCollectionService.getAll(), which dispatches the hero's QUERY_ALL EntityAction to the store.
  2. NgRx kicks into gear…
  3. The original EntityAction then goes to the EntityEffects.
  4. The effect selects an EntityDataService for that entity type. Data service is used to sends an HTTP request to the server
  5. The effect turns the HTTP response into a new success action with heroes (or an error action if the request failed)
  6. NgRx effect effects Dispatches that action to the store.

Let’s see each component in a detailed explanation:

Actions

Actions are one of the main building blocks in NgRx architecture. Actions represent unique events that happen throughout our application.

Actions are used in many ways in NgRx. Actions are the inputs and outputs of systems in NgRx. Actions help you to understand how events are handled in our application.

The Action interface
An Action in NgRx is formed by a simple interface:

interface Action {  
type: string; 
}

The interface has only one property, and it is the type that is represented as a string. The type property is for performing the action that will be dispatched in our application. Here the value of the type comes in the form of [Source] Event. value is used to provide a context of what category of action it is, and where the action was dispatched from. We add properties to an action to provide additional context or metadata for an action.

Below are examples of actions:

{
 type: '[Auth API] Login Success' 
}

After interacting with a backend API, this action describes an event triggered by a successful authentication.

{ 
type: '[Login Page] Login',
   username: string;
password: string;
 }

This action performs an event that is triggered by a user clicking on the login button from the login page in an attempt to authenticate a user. Additional metadata provided from the login page is defined as username and password.

Writing actions

There are some rules to writing effective actions within your application.

  • Upfront - it is used to write actions before developing new features to understand and gain a shared knowledge of that feature in advance.
  • Divide - Based on the event source it will categorize actions.
  • Many - As the more actions you write, the better you express flows in your application.
  • Event-Driven - capture events using that separating the description of an event and the handling of that event.
  • Descriptive - it provides an environment that is targeted to a unique event with more detailed information.

Let's see an example of an action that is initiating a login request.

import { createAction, props } from '@ngrx/store'; 
export const login = createAction(
 '[Login Page] Login', 
props<{ username: string; password: string }>()
 );

Above the createAction function returns a function. When called returns an object in the shape of the Action interface. To define any additional metadata needed for the handling of the action, the props method is used. Action creators provide a type-safe and consistent way to construct an action that is being dispatched.

To return the Action when dispatching, use the action creator.

onSubmit(username: string, password: string) { 
store.dispatch(login({ username: username, password: password })); 
}

The login action creator receives username and password as an object and returns a plain JavaScript object with a type property of [Login Page] Login, and username and password as additional properties.

The returned action has context about where the action came from and what event happened.

  • The category of the action is held within the square brackets [].
  • The category is used to make group actions for a particular area like a component page, backend API, or browser API.
  • The Login text after the category is a description of what event occurred from this action. In this case, to attempt to authenticate with a username and password the user clicked a login button from the login page.

Searching for Trusted AngularJS Development Company? Your Search ends here.

Reducers

Reducers in NgRx are responsible for handling transitions from one state to another state in our application. Reducer functions handle these transitions by determining which actions to handle. Reducers are pure functions it means that they produce the same output for a given input. They are without any side effects they handle each state transition synchronously. Each reducer function takes the current state, the latest Action dispatched, and determines whether to return a newly modified state or the original state.

Selectors

Selectors are pure functions used for pick up slices of store state. For optimizing this selection @ngrx/store provides some helper functions. When selecting slices of state selectors provide many features. The features are:

  • Portability
  • Memoization
  • Composition
  • Testability
  • Type Safety

When using the createSelector and createFeatureSelector functions the @ngrx/store keeps track of the latest arguments in which our selector function was invoked. The last result can be returned when the arguments match without reinvoking your selector function. This can provide performance benefits, particularly with selectors that perform expensive computation. This practice is known as memoization.

Conclusion

In this blog, we learned what is NgRx and NgRx store. We have gone through NgRx package categories like state, data, view and developer tooling. We have also learned the architecture and its main components like actions, reducer and selectors with example.

95