Make Your Angular NgRx Reducers an Eye Candy Using this Fantastic Library

Handle immutability in NgRx reducers with the ngrx-immer library.

NgRx is a popular state management library for Angular applications. It provides a centralized store for storing the application’s state and a set of tools for updating the state in a predictable manner. NgRx also provides a powerful set of reducers, which are functions that specify how the state should change in response to an action.

One of the core concepts in NGRX is immutability, which means that the state should never be modified directly. Instead, when an action is dispatched, the reducer creates a new copy of the state with the necessary changes. This helps ensure that the state remains predictable and that it can be easily tested and debugged.

However, creating a new copy of the state can be quite a pain, especially for complex state structures. To address this issue, ngrx-immer was created, which is a library that provides an easier way to handle immutability in NgRx reducers.

NgRx on method vs immerOn method

Consider a state with a list of users, where each user has a name and an age. We want to add a new user to the list, update the name of an existing user, and delete a user from the list.

Using the on method, we would write the following NGRX reducer:

import { createReducer, on } from '@ngrx/store';
import { addUser, updateUser, deleteUser } from './user.actions';

export interface User {
name: string;
age: number;
}

export const initialState: User[] = [];

export const _userReducer = createReducer(
initialState,
on(addUser, (state, { user }) => [...state, user]),
on(updateUser, (state, { user, name }) =>
state.map(u => (u.name === user.name ? { ...u, name } : u))
),
on(deleteUser, (state, { user }) =>
state.filter(u => u.name !== user.name)
)
);

Using the immerOn method from ngrx-immer, we would write the following NgRx reducer:

import { createReducer, immerOn } from 'ngrx-immer';
import { addUser, updateUser, deleteUser } from './user.actions';

export interface User {
name: string;
age: number;
}

export const initialState: User[] = [];

export const _userReducer = createReducer(
initialState,
immerOn(addUser, (state, { user }) => {
state.push(user);
}),
immerOn(updateUser, (state, { user, name }) => {
const index = state.findIndex(u => u.name === user.name);
state[index].name = name;
}),
immerOn(deleteUser, (state, { user }) => {
const index = state.findIndex(u => u.name === user.name);
state.splice(index, 1);
})
);

As you can see, the immerOn method provides a more intuitive and direct way of updating the state. It allows you to modify the state directly instead of creating a new object with the spread operator.

You don’t have to refactor your app — mix and match!

No need to rewrite all of your reducers.

You can use immerOn in the places that are the most complicated.

You can combine the immerOn method from the ngrx-immer library with the on method from the @ngrx/store library.

import { createReducer, on, immerOn } from 'ngrx-immer';
import { addUser, updateUser, deleteUser, togglePremium } from './user.actions';

export interface User {
name: string;
age: number;
premium: boolean;
}

export const initialState: User[] = [];

export const _userReducer = createReducer(
initialState,
on(addUser, (state, { user }) => [...state, user]),
immerOn(updateUser, (state, { user, name }) => {
const index = state.findIndex(u => u.name === user.name);
state[index].name = name;
}),
immerOn(deleteUser, (state, { user }) => {
const index = state.findIndex(u => u.name === user.name);
state.splice(index, 1);
}),
immerOn(togglePremium, (state, { user }) => {
const index = state.findIndex(u => u.name === user.name);
state[index].premium = !state[index].premium;
})
);

Almost no effort to use but makes a giant difference to your code readability and complexity.

Worthy of becoming part of the NgRx core library?

Do you think this should become a part of the core NgRx library? I vote that it should!

Why?

Installing multiple dependencies maintained outside of core libraries is always a risk of something that can stop being maintained.

Smaller lib, less maintainers = bigger risk.

And something as useful as this could come in a bundle with NgRx.

Don’t agree? Let’s discuss.

Sources

All credits go to fantastic Tim Deschryver — the author of this library.

Build Angular Apps with reusable components, just like Lego

Bit’s open-source tool help 250,000+ devs to build apps with components.

Turn any UI, feature, or page into a reusable component — and share it across your applications. It’s easier to collaborate and build faster.

Introduction to Angular | Bit

Learn more

Split apps into components to make app development easier, and enjoy the best experience for the workflows you want:

Micro-Frontends

Design System

Code-Sharing and reuse

Monorepo

Learn more:


Make Your Angular NgRx Reducers an Eye Candy 🍬 Using this Fantastic Library was originally published in Bits and Pieces on Medium, where people are continuing the conversation by highlighting and responding to this story.


This content originally appeared on Bits and Pieces - Medium and was authored by Daniel Glejzner

Handle immutability in NgRx reducers with the ngrx-immer library.

NgRx is a popular state management library for Angular applications. It provides a centralized store for storing the application’s state and a set of tools for updating the state in a predictable manner. NgRx also provides a powerful set of reducers, which are functions that specify how the state should change in response to an action.

One of the core concepts in NGRX is immutability, which means that the state should never be modified directly. Instead, when an action is dispatched, the reducer creates a new copy of the state with the necessary changes. This helps ensure that the state remains predictable and that it can be easily tested and debugged.

However, creating a new copy of the state can be quite a pain, especially for complex state structures. To address this issue, ngrx-immer was created, which is a library that provides an easier way to handle immutability in NgRx reducers.

NgRx on method vs immerOn method

Consider a state with a list of users, where each user has a name and an age. We want to add a new user to the list, update the name of an existing user, and delete a user from the list.

Using the on method, we would write the following NGRX reducer:

import { createReducer, on } from '@ngrx/store';
import { addUser, updateUser, deleteUser } from './user.actions';

export interface User {
name: string;
age: number;
}

export const initialState: User[] = [];

export const _userReducer = createReducer(
initialState,
on(addUser, (state, { user }) => [...state, user]),
on(updateUser, (state, { user, name }) =>
state.map(u => (u.name === user.name ? { ...u, name } : u))
),
on(deleteUser, (state, { user }) =>
state.filter(u => u.name !== user.name)
)
);

Using the immerOn method from ngrx-immer, we would write the following NgRx reducer:

import { createReducer, immerOn } from 'ngrx-immer';
import { addUser, updateUser, deleteUser } from './user.actions';

export interface User {
name: string;
age: number;
}

export const initialState: User[] = [];

export const _userReducer = createReducer(
initialState,
immerOn(addUser, (state, { user }) => {
state.push(user);
}),
immerOn(updateUser, (state, { user, name }) => {
const index = state.findIndex(u => u.name === user.name);
state[index].name = name;
}),
immerOn(deleteUser, (state, { user }) => {
const index = state.findIndex(u => u.name === user.name);
state.splice(index, 1);
})
);

As you can see, the immerOn method provides a more intuitive and direct way of updating the state. It allows you to modify the state directly instead of creating a new object with the spread operator.

You don’t have to refactor your app — mix and match!

No need to rewrite all of your reducers.

You can use immerOn in the places that are the most complicated.

You can combine the immerOn method from the ngrx-immer library with the on method from the @ngrx/store library.

import { createReducer, on, immerOn } from 'ngrx-immer';
import { addUser, updateUser, deleteUser, togglePremium } from './user.actions';

export interface User {
name: string;
age: number;
premium: boolean;
}

export const initialState: User[] = [];

export const _userReducer = createReducer(
initialState,
on(addUser, (state, { user }) => [...state, user]),
immerOn(updateUser, (state, { user, name }) => {
const index = state.findIndex(u => u.name === user.name);
state[index].name = name;
}),
immerOn(deleteUser, (state, { user }) => {
const index = state.findIndex(u => u.name === user.name);
state.splice(index, 1);
}),
immerOn(togglePremium, (state, { user }) => {
const index = state.findIndex(u => u.name === user.name);
state[index].premium = !state[index].premium;
})
);

Almost no effort to use but makes a giant difference to your code readability and complexity.

Worthy of becoming part of the NgRx core library?

Do you think this should become a part of the core NgRx library? I vote that it should!

Why?

Installing multiple dependencies maintained outside of core libraries is always a risk of something that can stop being maintained.

Smaller lib, less maintainers = bigger risk.

And something as useful as this could come in a bundle with NgRx.

Don’t agree? Let’s discuss.

Sources

All credits go to fantastic Tim Deschryver — the author of this library.

Build Angular Apps with reusable components, just like Lego

Bit’s open-source tool help 250,000+ devs to build apps with components.

Turn any UI, feature, or page into a reusable component — and share it across your applications. It’s easier to collaborate and build faster.

Introduction to Angular | Bit

Learn more

Split apps into components to make app development easier, and enjoy the best experience for the workflows you want:

Micro-Frontends

Design System

Code-Sharing and reuse

Monorepo

Learn more:


Make Your Angular NgRx Reducers an Eye Candy 🍬 Using this Fantastic Library was originally published in Bits and Pieces on Medium, where people are continuing the conversation by highlighting and responding to this story.


This content originally appeared on Bits and Pieces - Medium and was authored by Daniel Glejzner


Print Share Comment Cite Upload Translate Updates
APA

Daniel Glejzner | Sciencx (2023-04-14T13:09:14+00:00) Make Your Angular NgRx Reducers an Eye Candy Using this Fantastic Library. Retrieved from https://www.scien.cx/2023/04/14/make-your-angular-ngrx-reducers-an-eye-candy-using-this-fantastic-library/

MLA
" » Make Your Angular NgRx Reducers an Eye Candy Using this Fantastic Library." Daniel Glejzner | Sciencx - Friday April 14, 2023, https://www.scien.cx/2023/04/14/make-your-angular-ngrx-reducers-an-eye-candy-using-this-fantastic-library/
HARVARD
Daniel Glejzner | Sciencx Friday April 14, 2023 » Make Your Angular NgRx Reducers an Eye Candy Using this Fantastic Library., viewed ,<https://www.scien.cx/2023/04/14/make-your-angular-ngrx-reducers-an-eye-candy-using-this-fantastic-library/>
VANCOUVER
Daniel Glejzner | Sciencx - » Make Your Angular NgRx Reducers an Eye Candy Using this Fantastic Library. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2023/04/14/make-your-angular-ngrx-reducers-an-eye-candy-using-this-fantastic-library/
CHICAGO
" » Make Your Angular NgRx Reducers an Eye Candy Using this Fantastic Library." Daniel Glejzner | Sciencx - Accessed . https://www.scien.cx/2023/04/14/make-your-angular-ngrx-reducers-an-eye-candy-using-this-fantastic-library/
IEEE
" » Make Your Angular NgRx Reducers an Eye Candy Using this Fantastic Library." Daniel Glejzner | Sciencx [Online]. Available: https://www.scien.cx/2023/04/14/make-your-angular-ngrx-reducers-an-eye-candy-using-this-fantastic-library/. [Accessed: ]
rf:citation
» Make Your Angular NgRx Reducers an Eye Candy Using this Fantastic Library | Daniel Glejzner | Sciencx | https://www.scien.cx/2023/04/14/make-your-angular-ngrx-reducers-an-eye-candy-using-this-fantastic-library/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.