Steps for updating the same array in TypeScript

I have written a reducer code where I check if the same value is already present in the array. If it is, I update the previous value instead of pushing the same value again.

Here is my code snippet:

export function reducer(
      state: IDeviceState = initialState,
      action: DeviceActions.AllDeviceActions
    ): IDeviceState {
      switch (action.type) {
        case DeviceActions.GET_DEVICE_BY_ID_SUCCESS: {
          const { payload } = action;
          const devices = Array.isArray(payload)
            ? payload
                .map(pushBranches)
                .flat()
                .filter((device) => device !== null)
            : [pushBranches(payload)].filter((device) => device !== null);

          const updatedDevices = devices.filter((device) => {
            const existingDevice = state.devices.find(
              (d) => d.result?.unitId === device.result.unitId
            );

            return !existingDevice;
          });

          return {
            ...state,
            devices: state.devices.concat(updatedDevices),
            loading: false,
            loaded: true,
            error: null,
          };
        }
        default: {
          return state;
        }
      }
    }

    function pushBranches(devices: any) {
      if (devices.result) {
        return devices;
      }
      return null;
    }

Answer №1

It appears that your scenario involves handling an array of objects in your state, each with a unique key (presumably identified by the unitId property). The task at hand is to perform an "upsert" operation, where existing objects are updated or new ones inserted based on matching unitId.

The upsert process can be broken down into two main steps:

  • Remove any objects from the state that have a matching unitId found in the payload.
  • Add all objects from the payload to the state.

On a side note, naming your action as

GET_DEVICE_BY_ID_SUCCESS</code may not be very indicative of its purpose. Since actions are meant for modifying state, a more suitable name could be <code>DEVICE_UPSERT
or similar.

If your action can accept both single object payloads and arrays, you can streamline the process by converting the payload to an array if it's not already:

const payloadArray = Array.isArray(payload) ? payload : [payload];

This ensures that you're always working with an array while operating on payloadArray.

To handle the deletion phase of the upsert, where existing devices need to be removed, adjust your logic to filter out devices from the state that are present in the payload:

const remainingDevices = state.devices.filter(stateDevice => devices.every(
    d => d.result?.unitId !== stateDevice.result?.unitId
));

The resulting remainingDevices array will only contain devices that were not included in the payload. By using the every method, we ensure that no device with a matching unitId is retained in this array.

Finally, simply combine this array with the devices from the payload using concat to update the state with the new set of devices.

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

What is the functionality of resetting an index using the modulus operator?

I'm struggling to grasp the concept of modulus, especially when it comes to resetting an array index. Take for example this code snippet: let numbers = [1, 2, 3] let index = 0 for 1...6 { let item = numbers[index % numbers.count] print(item) ...

Is there a way to use Regex to strip the Authorization header from the logging output

After a recent discovery, I have come to realize that we are inadvertently logging the Authorization headers in our production log drain. Here is an example of what the output looks like: {"response":{"status":"rejected",&quo ...

The most effective method for monitoring updates to an array of objects in React

Imagine a scenario where an array of objects is stored in state like the example below: interface CheckItem { label: string; checked: boolean; disabled: boolean; } const [checkboxes, setCheckboxes] = useState<CheckItem[] | undefined>(undefined ...

What is the method for retrieving the second type of property from an array of objects?

I have a collection of objects that map other objects with unique identifiers (id) and names (name). My goal is to retrieve the name corresponding to a specific id. Here is my initial approach: const obj = { foo: { id: 1, name: 'one' }, ...

"Exploring the best way to open a new tab in Angular from a component

I am working on a simple Angular application with two components. My goal is to open one component in a new tab without moving any buttons between the components. Here is an overview of my application setup: Within my AppComponent.html file, there is a b ...

Arranging multi-level array with distinct keys and values

Users have the ability to add custom fields on a form. Note: I am looking for ways to streamline and organize the code more efficiently, with further explanations to follow. The HTML structure has been simplified for clarity: <form action="" method=" ...

Encountering Error 404 while submitting a form on Prisma, Axios, and NestJS

Currently, I am working on a Sign Up page using SolidJs and NestJS with Prisma. However, when I try to submit the form, I encounter an error that says POST 404 (Not Found) and this error is also returned by axios. Additionally, my setup includes postgres ...

Setting a TypeScript version in Atom: Step-by-step guide

I'm currently grappling with using a specific version of TypeScript in Atom. For an older project that relies on Backbone, the latest TypeScript version doesn't compile properly, so I need to use an earlier one. The closest solution I've co ...

Listen for incoming data from the client in the form of an ArrayBuffer

I have been utilizing the ws library within nodejs to develop a small cursor lobby where players can interact. I have managed to utilize the server to send ArrayBuffers with bit streams to the client and successfully decode them. However, I am encountering ...

Encountering an Error: Unforeseen Token < Causing Webpack Configuration Problem in Typescript

Seeking assistance to resolve an issue that has arisen while working on a project with Typescript, React, and Webpack. I referred to the guide available at https://www.typescriptlang.org/docs/handbook/react-&-webpack.html After configuring everything, ...

Using React and TypeScript, open the initial tab from a mapped array with an accordion component

{accordion.map(accordionItem => ( <AccordionItem key={accordionItem.title} text={accordionItem.text} title={accordionItem.title} ></AccordionItem> ...

Leveraging functions with Ng-Repeat

I am currently dealing with two different arrays of objects. The first array contains a list of permissions groups, while the second array consists of user groups. My main goal is to compare the Group Owner (which is represented by ID 70) with the list of ...

Comparison of list mutation using for-in loop vs. range(len) in Python

What is the reason for the lack of mutation in the list passed below: def modify(listarg): for x in listarg: x=x*2 While this results in mutation: def modify(listarg): for x in range(len(listarg)): listarg[x]=listarg[x]*2 ...

A method for performing precise division on numbers in JavaScript, allowing for a specific precision level (such as 28 decimal places)

I've searched extensively for a library that can handle division operations with more than 19 decimal places, but to no avail. Despite trying popular libraries like exact-math, decimal.js, and bignumber.js, I have not found a solution. How would you ...

Understanding the complexity of defining the type of a function can be challenging. If you're tasked with a complicated function, determining its type

Let's break it down: Dict is defined as { [key: string]: () => any } The desired return value is represented by X I am attempting to create a type for a function that: Takes in a dictionary Dict T Returns an X Now, X also functions as a functio ...

Are there alternative methods for eliminating specific objects and their values from an array, aside from utilizing array_splice?

I am trying to delete the values of "email" and "phone_number" from my array before submitting it to MSSQL because I do not store this information there. Despite searching online, it seems like the only solution I have come across is using array_splice. Ar ...

Leveraging ng-repeat to iterate through JSON data from an API within a for loop

I'm currently working on a small AngularJS app that interacts with a news API to fetch data. I've managed to retrieve an array of 10 articles from a list of 10 news sources provided by the API using a for-loop as shown below. However, I've e ...

My component is displaying a warning message that advises to provide a unique "key" prop for each child in a list during rendering

I need help resolving a warning in my react app: Warning: Each child in a list should have a unique "key" prop. Check the render method of `SettingRadioButtonGroup`. See https://reactjs.org/link/warning-keys for more information. at div ...

Access data from JSON array in Angular 2

I'm facing a basic issue here. I have a JSON file named pageDefinition.json that is being loaded into my component. Here's how the JSON data looks: ... "testArray": [ {"id": 0, "name": "row1"}, {"id": 1, "name": "row2"}, {"id": 2, "n ...

Issues arising with code splitting using React HashRouter in a project utilizing Typescript, React 17, and Webpack 5

Encountered build issues while setting up a new project with additional dependencies. package.json: { "name": "my-files", "version": "1.0.0", "description": "App", "main": " ...