Exploring the capabilities of Redux Toolkit's createEntityAdapter in designing versatile data grids

Seeking guidance on utilizing createEntityAdapter from Redux Toolkit.

In my application, I display package information and details using the master/detail feature of the AG Grid library. Packages are loaded initially, followed by fetching detailed data as each package is expanded.

I intend to manage the data in a normalized way with createEntityAdapter, but struggling with handling dynamic nature of detail grids. Currently, I create a new property in the reducer slice for every set of detail records loaded, using the parent package row's ID as the key. This results in the data slice looking like:

{
  PACKAGES: [{ id: 123, ...otherData }, { id: 124, ...otherData }],
  '123': [{ id: 456, ...otherDetailData }],
}

When user expands the 124 package row, its detail data gets fetched, resulting in:

{
  PACKAGES: [{ id: 123, ...otherData }, { id: 124, ...otherData }],
  '123': [{ id: 456, ...otherDetailData }],
  '124': [{ id: 457, ...otherDetailData }],
}

Although I could separate the PACKAGES data into its own entity adapter, doing the same for detail grids isn't feasible due to unknown details upfront.

Encountering a similar issue as mentioned in this thread.

Considering consolidating all detail data in a single entity adapter and maintaining another index based on parent id, but concerned about keeping it synchronized.

Any suggestions? What approach would be advisable in such case?

Answer â„–1

Redux Toolkit is a project that I developed and continue to maintain. Recently, I had a task that was somewhat similar involving nested entity adapters.

In my specific scenario, I had to ensure that additional data sets were managed as new parent items were added or removed.

interface ChildrenEntry {
  parentId: ParentId;
  children: EntityState<ChildType>
}

interface ChildrenData {
  parentId: ParentId;
  children: ChildType[];
}

interface NewChildAdded {
  parentId: ParentId;
  child: ChildType;
}

export const childEntriesAdapter = createEntityAdapter<ChildrenEntry>();
export const childrenAdapter = createEntityAdapter<ChildType>();

const initialState = childEntriesAdapter.getInitialState();

const createNewChildEntry = (parentId: ParentId) => ({
  parentId,
  children: childrenAdapter.getInitialState()
});

const childEntriesSlice = createSlice({
  name: "children",
  initialState,
  reducers: {
    childEntriesLoaded(state, action: PayloadAction<ChildrenData>) {
      const {parentId, children} = action.payload;
      const childEntry = state.entities[parentId];
      if (childEntry) {
        childrenAdapter.setAll(childEntry.children, children);
      }
    },
    // etc
  },
  extraReducers: builder => {
    builder
      .addCase(parentLoaded, (state, action) => {
        const childEntries = action.payload.map(parent => createNewChildEntry(parent.id));
        childEntriesAdapter.setAll(state, childEntries);
      })
      .addCase(parentDeleted, (state, action) => {
        childEntriesAdapter.removeOne(state, action);
      })
      .addCase(parentAdded, (state, action) => {
        const childEntry = createNewChildEntry(action.payload.id);
        childEntriesAdapter.addOne(state, childEntry);
      });
  }
})

There may be alternative approaches to handling this situation, but the method I used served its purpose effectively for me.

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

Extract the body.req object within a loop in a Node.js application

I'm looking to efficiently parse and save the body of a POST request using Mongoose in Node.js. Is there a way to use a for loop to accomplish this task, rather than manually saving every property? My ideal solution would involve something like: for ...

Alter the arrow to dynamically point towards the location of the click source

I am currently working on creating a popover dialog that should point to the element triggering its appearance. The goal is for the arrow to align with the middle of the button when clicked. While I am familiar with using CSS to create pointing arrows, th ...

Issue with React state not updating as per expectation, values in body are not being identified by backend system

I am currently facing a puzzling situation with a component in my React application. This component conditionally sets values based on state and button clicks, then sends the data object to RTK Query and ultimately to a controller in mongoose/express. Two ...

Retrieve information from various MongoDB collections

Greetings! I currently have a database with the following collections: db={ "category": [ { "_id": 1, "item": "Cat A", }, { "_id": 2, "item": "Cat B" ...

Having trouble getting the new React app to run with the yarn start command - it just doesn't

An error has occurred. See the details below: yarn run v1.22.17 $ react-scripts start node:internal/modules/cjs/loader:488 throw e; ^ Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath './lib/tokenize' is not defined by "exp ...

Revamping the values attribute of a table embedded in a JSP page post an AJAX invocation

I am encountering an issue with displaying the content of a table. The table's data is retrieved via an AJAX request when clicking on a row in another table on the same page. Here is my code for the JSP page: <table id="previousList" class="table" ...

The use of the .reset() function in typescript to clear form data may lead to unexpected

I've been trying to use document.getelementbyID().reset(); to reset form values, but I keep running into an error in TypeScript. Property 'reset' does not exist on type 'HTMLElement'. Here's how I implemented it: const resetB ...

When the input is altered, retrieve all input values within the div and then proceed to update the corresponding

The HTML provided is structured as follows: <div class="filters"> <div class="filter-label">6</div> <div class="filter-inputs"> <input type="number" name="i1" id="i1" value="1" min="0" step="1" /> & ...

What is the best way to change the default text color for a selected tab in mui/material/Tab component in React?

To make the blue color change to red. click here for image description <Tabs value={this.state.value} onChange={this.handleChange} textColor="primary" indicatorColor="pri ...

subscribing to multiple observables, such as an observable being nested within another observable related to HTTP requests

Hello, I recently started learning Angular and I am facing a challenge with posting and getting data at the same time. I am currently using the map function and subscribing to the observable while also having an outer observable subscribed in my component. ...

What is the reason for multiple ajax functions being triggered when submitting a form through ajax?

I have a Drupal form with an AJAX submit. Additionally, I have another jQuery $.get function that sends a request every 2 minutes and inserts the response into an HTML element. The form and this JavaScript code are independent of each other, performing sep ...

Transforming a single object into multiple arrays using AngularJS

Just starting out with AngularJS and I've got some data that looks like this { day1: 0, day2: 0, day3: 0, day4: 2 } Is there a way to convert this data into arrays structured like below? [     ["day1": 0],     ["day2": 0],   ...

How to convert typescript path aliases into relative paths for NPM deployment?

I am currently working on a typescript project that utilizes paths for imports. For instance: "paths": { "@example/*": ["./src/*"], } This allows the project to import files directly using statements like: import { foo } from "@example/boo/foo"; Whe ...

Stop all file uploads using jQuery

I have integrated the jQuery File Upload plugin () into my website for image uploads. Here is my code snippet: $('#fileupload').fileupload({ url: 'server/index.php', dataType: 'json', dropZone: $('#dropzone&a ...

The connections of directives

In my Angular application, I am encountering an issue while trying to enhance the functionality of a third-party directive with my own custom directive. The problem lies in the order of instantiation of these directives. The intended usage of the directiv ...

Setting up WebPack for TypeScript with import functionality

A tutorial on webpack configuration for typescript typically demonstrates the following: const path = require('path'); module.exports = { ... } Is it more advantageous to utilize ES modules and configure it with import statements instead? Or is ...

Show items in the sequence of clicking

Is there a way to display elements in the order they're clicked, rather than their order in the HTML using jQuery? For example: CSS code: .sq{ display:none; } HTML Code: <a href="#" id="1">A</a> <a href="#" id="2">B</a> ...

What is the best way to deselect radio buttons in one section when choosing a radio button in a different section?

As a newcomer to React, I need some help clarifying this issue. I want to deselect one radio button when another is selected in a specific section. Currently, I am utilizing Material UI's RadioGroup component. For any necessary code changes, please re ...

Tips for removing markers from personal Google Maps

I am having trouble deleting markers from my Google Maps using my code. The markers array seems to be empty even after adding markers. Can anyone help me troubleshoot this? Thank you! When I use console.log(markers.length) in the removeMarkers() function, ...

I am unable to load any HTML files in my VueJS iframe, except for the index.html located in the public

Within the template of my vue component, I am utilizing the following code: <iframe width="1000vw" height="600vh" src="../../public/myHtmlFile.html"></iframe> Unfortunately, the file specified in the src attribut ...