Top tips for accessing and modifying an immutable object within a component retrieved from an RXJS/NGRX store in Angular

This week we successfully updated our Angular v9 app to v11 and RXJS v6.6 with minimal issues. However, due to the store being in freeze mode, we are encountering errors when trying to update the store in certain areas of our code.

While most of the issues can be resolved easily in helper methods used in reducers, one common approach in our edit components is causing complications.

In these edit components for complete models/items, we typically follow this workflow:

  • Retrieve the item from the store using RXJS operators such as filter, map, etc.
  • Assign it to a property within the component in a subscribe block (as observable objects cannot be directly edited).
  • Attempt to make edits using ngModel in the view or other component code.

This often leads to "Cannot assign to read-only property..." errors. While creating a shallow copy using spread or Object.assign() resolves some cases, more complex objects require a deep copy.

Is there a more effective way to retrieve an item from an RXJS/NGRX store for editing without resorting to custom code to generate a deep copy within the component? Currently, we are working around the issue by using JSON.parse(JSON.stringify(Object)), but it doesn't seem like the optimal solution!

Answer №1

While this might not directly address your question, I hope it provides some clarity for you.

Consider a scenario where you add an object to your store and modify one of its properties. This change will be reflected both in the store and locally because objects and arrays are reference types. It is important to only alter properties in the store through actions and ensure that updates occur immutably within the reducer in order to facilitate time travel debugging.

You can find additional insights on this topic at this link.

In terms of techniques for creating copies, Object.assign and JSON.parse(JSON.stringify(Object)) are viable options, as you mentioned.

Alternatively, you can create copies by spreading an array [...array] or an object { ...object }.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Angular 2 testing error: Unable to connect to 'ngModel' as it is not recognized as a valid property of 'input'

Currently, I am experimenting with angular2 two-way binding for the control input. Below is the issue that I encountered: An error occurred: Can't bind to 'ngModel' since it isn't a known property of 'input'. Contents of app. ...

Updating the state in a different component using React and Typescript

The Stackblitz example can be found here I'm attempting to update the useState in one component from another component. Although it seems to work here, it's not functioning properly in my actual application. Here is a snippet of the app.tsx co ...

Preventing Repeated Form Submissions in Angular: A Helpful Guide

`Hello, I am new to Angular and I am struggling with a specific part of the form. People have been clicking the submit button multiple times quickly, causing the same information to be added repeatedly before it can be sent to the API. I have searched onl ...

What sets apart the states of the select tag from other input tags in Angular?

I am having trouble displaying an error message for a select tag when it is in a touched state. The error handling seems to be working fine for other input tags, but not for the select tag. Below is the code snippet: <div class="form-g ...

Problem with dynamic page routes in Next.js (and using TypeScript)

Hi everyone, I'm currently learning next.js and I'm facing an issue while trying to set up a route like **pages/perfil/[name]** The problem I'm encountering is that the data fetched from an API call for this page is based on an id, but I wa ...

Encountering an issue where the useMutation function is not recognized on the DecorateProcedure<MutationProcedure> type while attempting to utilize the useMutation feature

Currently, I am utilizing the NextJS app router. I am attempting to invoke a rather straightforward route: import { z } from "zod"; import { createTRPCRouter, publicProcedure } from "~/server/api/trpc"; // document sending user email to waitlist da ...

JavaScript maintaining records and connections between multiple asynchronous events

I am working on an Angular 10 project where users can compress and upload images to Google Cloud Storage. The compression and uploading functionalities are functional, but I'm facing challenges with managing the asynchronous process of handling multip ...

Load a lazy module in Angular that contains a nested router-outlet

I am encountering an issue with my Angular CLI application that has multiple lazy loaded modules, some of which have their own router-outlets. When trying to directly route to a specific path in a lazy loaded module, it seems like the browser is attempting ...

The function slice is not a method of _co

I'm attempting to showcase the failedjobs array<any> data in a reverse order <ion-item *ngFor="let failjob of failedjobs.slice().reverse()"> An issue arises as I encounter this error ERROR TypeError: _co.failedjobs.slice is not a fu ...

What is the best way to implement persistStore in Redux-Toolkit?

Here is my setup: import AsyncStorage from '@react-native-async-storage/async-storage' import { persistStore, persistReducer } from 'redux-persist'; import { configureStore } from "@reduxjs/toolkit"; import { searchReducer } f ...

Running complex operations within a sorting function just once

I am facing the challenge of sorting an array of objects based on multiple date fields, with the added complexity of excluding certain dates depending on the category. In order to optimize performance, I want to minimize the number of times the getUsefulJo ...

Is it possible for the Observable call in Angular 4 to function similarly to jQuery's synchronous AJAX method?

As I have a business logic function that needs to use HttpGet and I must wait for the result before continuing, jQuery's ajax can handle this easily. But I am curious if Observables have a similar feature? I was hoping for the result to be: John An ...

Issue encountered while creating production build using Ionic

I've encountered a perplexing error that has me stumped. The error reared its head while attempting to build with --prod. Despite my efforts to fix it by updating dependencies, when I run ionic cordova build android --prod --verbose, the following er ...

Only implement valueChanges on the second step of the form

I am utilizing the mat-stepper with a single form. My stepper has two steps only. I am looking to make an API request for every input value change, but only when the user is on the second step. How can I accomplish this? .ts ngOnInit() { this.formGr ...

Creating nested return types: A guide to defining function return types within a Typescript class

My large classes contain functions that return complex objects which I am looking to refactor. class BigClass { ... getReferenceInfo(word: string): { isInReferenceList:boolean, referenceLabels:string[] } { ... } } I am considering somethi ...

The error message "Property 'data1' is not a valid property on the object type {}"

const Page: NextPage = ({data1}:{data1:any}) => { const [open, setOpen] = React.useState(false); const [data, setData] = React.useState(data1); const handleAddClick = () => { setOpen(true); }; ..... } export async function getServerS ...

What is the recommended default value for a file in useState when working with React and TypeScript?

Can anyone help me with initializing a file using useState in React Typescript? const [images, setImages] = useState<File>(); const [formData, setFormData] = useState({ image: File }); I'm facing an issue where the file is sho ...

What is the significance of requiring a specific string in a Typescript Record when it is combined with a primitive type in a union?

I am facing an issue with the following data type: type ErrorMessages = Record<number | 'default', string>; When I declare a variable like const text: ErrorMessages = {403: 'forbidden'}, Typescript points out that default is miss ...

Utilizing useClass in Angular's APP_INITIALIZER

Before my application starts up, I require some API data and am currently handling it with APP_INITIALIZER and useFactory. However, I aim to enhance the structure by separating all the code from app.module.ts: app.module.ts import { NgModule} from '@ ...

The type inference in TypeScript sometimes struggles to accurately determine the type of an iterable

Struggling to get TypeScript to correctly infer the underlying iterable type for the function spread. The purpose of this function is to take an iterable of iterable types, infer the type of the underlying iterable, and return a new iterable with that infe ...