State not being updated by ngrx forms 8 reducer

I am currently utilizing ngrx-forms with the ngrx 8 syntax to sync my form and state store. The actions for updating the form state are being dispatched successfully, like so:

{
  controlId: 'adForm.location.community',
  value: 'wst',
  type: 'ngrx/forms/SET_VALUE'
}

Despite this, the state remains unchanged, as there is no difference observed in the Redux dev tools after executing the above action.

This is how my reducer is structured:

export const reducer = createReducer(
  initialAdFormStoreState,
  onNgrxForms(),
  // Other action handlers
  // ...
)

export const adFormReducer = wrapReducerWithFormStateUpdate(
  reducer,
  (s) => s.data.form,
  adFormValidators,
)

The initial state is set up like this:

const initialAdFormStoreState: AdFormStoreState = {
  data: {
    form: createFormGroupState<AdForm>('adForm', { /* ... */ })
    // ...
  },
  // ...
}

I have reviewed the documentation for updating states multiple times, and everything seems to be in order.

Answer №1

onNgrxForms() specifically targets forms located at the top level of the feature state object. It was not reflecting changes in my state because I had placed the form under data.form after splitting state into ui/data. I needed to bring it up a level for it to work properly. Another option is to create your own version of onNgrxForms().

Answer №2

According to Moo, it seems that the built-in function onNgrxForms() only checks the top level of the state, requiring a custom implementation for deeper inspection.

In my own experience, I encountered a similar challenge when tasked with creating virtual tabs that could be independently stored and displayed.

I ended up devising two implementations: one straightforward approach capable of checking a two-level state (currently utilized in my production project) and a more generic solution that works recursively.

This code is inspired by the ngrx-forms implementation of onNgrxForms(). For specific details, refer to the links below:

https://github.com/MrWolfZ/ngrx-forms/blob/master/src/reducer.ts https://github.com/MrWolfZ/ngrx-forms/blob/master/src/state.ts

State

export interface MyObject {
    property: string;
}

export interface MyObjectFormValue {
    property: string;
}

export interface Substate {
    data: MyObject;
    form: FormGroupState<MyObjectFormValue>;
}

export interface State {
    [id: number]: Substate;
    commonData1: any[];
    commonData2: boolean;
}

The State interface includes various Substates containing FormGroupState. While these can be accessed through an indexer, your implementation may solely rely on the field data.

If desired, you can incorporate shared common data (such as fields commonData1 and commonData2) among the Substates.

Straightforward Approach

import { ALL_NGRX_FORMS_ACTION_TYPES, formStateReducer } from 'ngrx-forms';

function isSubstate(object: any): object is Substate {
    return (
        Boolean(object) &&
        Object.prototype.hasOwnProperty.call(object, 'data') &&
        Object.prototype.hasOwnProperty.call(object, 'form')
    );
}

// Rest of the straightforward approach omitted for brevity

A simple method utilizing Object.entries is applied due to the potentially unknown nature of Substates within the State. Direct access is possible if predefined keys are in place.

Generic Approach

// Generic approach using immer library
// Relevant functionality provided within this section

This version leverages the immer library for immutable state updates.

It's worth noting that the function isFormState isn't part of the library's public API, hence manual inclusion was required. Additionally, the introduction of a set visits helps prevent issues related to circular references, while isObject aids in filtering out certain properties during verification.

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

Navigating with the Angular router to a child route is causing a redirection to the 404

I'm facing a challenge with navigating to a child component from the parent view. This is how my app-routing configuration looks: const routes: Routes = [ { path: '', redirectTo: 'home', pathMatch: 'fu ...

Angular 2 fails to apply active class colors to tabs in a modal popup

https://i.sstatic.net/T8lIu.pnghttps://i.sstatic.net/O21ZO.pngIn my modal popup, I have multiple tabs in the modal body. The issue I am facing is that when the modal is invoked, the active tab color is not being applied. The modal itself is built using ngx ...

Navigating with finesse in Angular2

My goal is to generate dynamic routes using the index names from my elastic index. I successfully implemented dynamic routing by manually adding some names, but encountered an issue when trying to insert routes with my elastic index names. In my app.routi ...

What is the best way to ensure that GCM push notifications are still received even when the app is closed or the

Currently, I'm in the process of developing an application using Ionic 2 that requires push notifications to be received. In certain scenarios, such as when the app is force-stopped on Android or when the device is turned off, push notifications are ...

What is causing the error message "Module '@reduxjs/toolkit' or its type declarations are not found" to appear?

Although I have a good understanding of React-Redux, I decided to delve into TypeScript for further practice. Following the recommended approach from the react-redux team, I created a new project using the TS template: "npx degit reduxjs/redux-templa ...

Setting up VSCode to run various tasks

My TypeScript project in Visual Studio Code has a specific task outlined as follows: { "version": "0.1.0", // The command is tsc. "command": "tsc", // Show the output window only if unrecognized errors occur. "showOutput": "silent", // Und ...

Converting Data Types in Typescript

So I'm working with Data retrieved from a C# Rest Server. One of the values in the array is of type Date. When I try to perform calculations on it, like this: let difference = date1.getTime() - date2.getTime(); I encounter the following error messag ...

Display or conceal elements within a Component with the help of a Service

After developing a custom Tabs component, I have implemented it in the following way (StackBlitz example): <tabs> <tab title="Tab 1"> <div toolbar> <message><span>Message 1: </span></message> &l ...

Define a module function that can be used externally

I am encountering an issue while trying to declare an external module that does not have existing typings. This library has a function that returns a string and takes no arguments. My attempt to define it in a .d.ts file is as follows: declare module "c ...

Encountering an issue while trying to deploy my node.js application on Heroku

While monitoring the Heroku logs using the command heroku --tail, I encountered the following error: Error: 2022-01-25T19:10:06.153750+00:00 app[web.1]: at emitErrorCloseNT (node:internal/streams/destroy:122:3) 2022-01-25T19:10:06.157055+00:00 heroku[rout ...

What is the method to declare data types within the map function?

When retrieving data from a server, I receive an object that includes four arrays with different types of objects. I am attempting to map this data before subscribing to the observable so that I can properly utilize the classes in my frontend: getData(){ ...

The Tauri JS API dialog and notification components are failing to function, resulting in a null return value

Currently, I am getting acquainted with the tauri framework by working on a small desktop application. While testing various tauri JS API modules, most of them have been functioning as expected except for the dialog and notification modules. Whenever I tes ...

The error thrown is: Module 'typeorm' not found

Whenever I attempt to execute the (.exe) file of my ElectronJS project that was created using Angular, I keep encountering this specific error. What steps should I take in order to resolve this issue? ...

Tips for correctly setting object initial values in React CreateContext

How can I correctly define the initial value of the constance trainsDetails in React Create Context? The trainsDetails is an object with various properties, fetched as a single object from an endpoint and has the values specified below in the TrainsDetails ...

Dynamic table row that expands to show additional rows sourced from various data sets

Is there a way to expand the table row in an angular-material table when it is clicked, showing multiple sets of rows in the same column as the table? The new rows should share the same column header but not necessarily come from the same data source. Whe ...

Tips for showcasing the output information in react framework

I'm currently developing a project that involves using rabbitMQ and react. After successfully connecting my rabbitMQ server to my react app, I was able to retrieve data from the server. Although I can output this data to the console using console.lo ...

Angular: ngModelChange not updating value in dropdown menu

I have successfully implemented a dropdown feature like this: <select (ngModelChange)="onChange($event)"> <option *ngFor="let quantity of quantities" [ngValue]="quantity"> {{ quantity }} ...

What is the best way to implement a dynamic back button in Next.js?

Being familiar with creating a standard back button, I am now eager to craft one that directs the user back by one step in the URL rather than returning to the previous page. This way, I can utilize the button in various locations without needing to alter ...

Error: The function 'some' is not recognized in the rawData variable in REACT/ANTDESIGN

I've been grappling with this issue for nearly a full day now. Despite exhausting all possible solutions and conducting extensive searches, I'm still stumped. My task is to create a table using ant design where all the users are displayed upon i ...

The 'SVGResize' or 'onresize' property is not available on the 'SVGProps<SVGSVGElement>' type

Using React with SVG I'm facing an issue with handling the resizing event of an svg element. I have looked into using the SVGResize and onresize events, but encountered compilation errors when trying to implement them: const msg1 = (e: any) => co ...