How come I am unable to expand a collection of objects using Zustand?

I am currently utilizing Zustand in a TypeScript Next.js application. Strangely, whenever I attempt to loop through my state object, I encounter a runtime error message.

The structure of the damaged zone object for my car is as follows:

const damagedZones = {
  Left: {
    front_door:[
      {
        id: 1,
        picture1: 'picture 1 base64 string',
        picture2: 'picture 2 base64 string',
        comment: 'any comment'
      },
      {
        id: 2,
        picture1: 'picture 1 base64 string',
        picture2: 'picture 2 base64 string',
        comment: 'any comment'
      }
    ],
    back_door: [
    ],

Assuming I add a new element to my "front_door" array, here is the relevant zustand store and function: In the provided code snippet, the variable "zone" would correspond to the "Left" key in my damagedZones object, while "element" would represent the "front_door" key.

export const useDamagedZones = create<DamagedZonesProps>((set) => ({
  damagedZones: damagedZones,
  setDamagedZones: (elementItem: damagedItem, zone: string, element: string) => {
    set(state => ({
      damagedZones: {
        ...state.damagedZones,
        [zone]: {
          ...state.damagedZones[zone],
          [element]: [
            ...state.damagedZones[zone]?.[element],
            elementItem
          ]
        }
      }
    }))
  },
}))

Upon triggering this function, I receive a runtime error that states:

TypeError: Invalid attempt to spread non-iterable instance. Non-array objects must have a Symbol.iterator method in order to be iterable.

I'm perplexed by this issue.... While using an object with ids as keys instead of arrays solves the problem, it's not as convenient. An array is more suitable in this scenario, yet it's not working as expected....

Answer №1

After some thought, I realized that the issue was due to my misunderstanding of the typescript types for my damagedZone object! I neglected to mention that one key should be an array :)

It now works perfectly with my object type structured like this:

type damagedItem = {
  id?: number 
  picture1?: string | null,
  picture2?: string | null,
  picture3?: string | null,
  comment?: string,
}

type DamagedElement = {
  [key: string]: damagedItem[]
}

type DamagedZone = {
  step1_gauche: DamagedElement,
  step1_droite: DamagedElement,
  step1_avant: DamagedElement,
  step1_arriere: DamagedElement
}

Below is the current implementation of the store useDamagedZones:

export const useDamagedZones = create<DamagedZonesProps>((set) => ({
  damagedZones: damagedZones,
  setDamagedZones: (elementItem: damagedItem, zone: string, element: string) => {
    set(state => ({
      damagedZones: {
        ...state.damagedZones,
        [zone]: {
          ...state.damagedZones[zone],
          [element]: [
            ...state.damagedZones[zone]?.[element],
            elementItem
          ]
        }
      }
    }))
  },
  removeDamagedItem : (zone: string, element: string, id: number ) => {
    set(state => ({
      damagedZones: {
        ...state.damagedZones,
        [zone]: {
          ...state.damagedZones[zone],
          [element]: 
            state.damagedZones[zone]?.[element].filter(el => el.id !== id)
        }
      }
    }))
  }
}))

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

Is there a way to identify the moment when a dynamically added element has finished loading?

Edit: I've included Handlebar template loading in my code now. I've been attempting to identify when an element that has been dynamically added (from a handlebars template) finishes loading, but unfortunately, the event doesn't seem to trig ...

Encountering Deployment Issues with Next.js and Docker due to MongoDB Buffering Delay of 1000

Hey everyone, I'm facing an issue after deploying my project using Docker. When I try to access the site, I encounter an application error that indicates a server-side exception has occurred. The server logs contain more information, with the digest r ...

In AngularJS, modifying the value of a copied variable will result in the corresponding change in the value of the main

I'm facing a peculiar issue. I have an array of objects and I used angular.forEach to update the price key value of each object. However, when I make changes in each object, it also affects the main array object. Take a look at the code snippet below ...

Is it possible to swap the src of the Next.Js Image Component dynamically and incorporate animations in the

Is there a way to change the src of an image in Nextjs by using state and add animations like fadein and fadeout? I currently have it set up to change the image source when hovering over it. const [logoSrc, setLogoSrc] = useState("/logo.png"); <Image ...

Having trouble with my Express app due to errors popping up because of the order of my routes

app.get('/campgrounds/:id/edit', async (req,res) =>{ const campground = await Campground.findById(req.params.id) res.render('campgrounds/edit', { campground }); }) app.get('/campgrounds/:id', async (req,res) =>{ ...

Demonstrating the transformation of child elements into parent elements through angular 6 ngFor

I have a JSON array dataset where each object may contain nested arrays. In order to display the inner nested array elements as part of the parent array using Angular's NgFor, I need to format the input like this: [{ 'id': 1, 'tit ...

A guide on how to insert content into a text area using a drop-down menu choice

I'm a total beginner at this. Is it possible to use JavaScript to automatically fill in a text area on an HTML form based on what is selected in a drop-down menu? If so, can someone please explain how to achieve this? ...

I am facing an issue where my Popover functions correctly when elements are added using HTML, but not when they are dynamically created

I'm currently working on a method to incorporate multiple popovers that have a similar appearance to the following: The screenshot of my first JsFiddle project (click to view) The initial progress I've made can be seen in my first JsFiddle, acc ...

After a page reload, Material-UI stops functioning properly

I am currently working with Material UI in a Next.js project. When I run npm run dev, everything looks good. However, whenever I refresh the page, all the styling breaks. Has anyone experienced this issue before? It seems like Material-UI is no longer func ...

Frontend Will Not Be Able to Access Cloud Run Environment Variables when in Production

My current setup involves using docker to build an image through Google Cloud Build and Google Cloud Registry. I have Pub/Sub triggers in place to populate Cloud Run instances with new Docker images upon a successful build. The issue I am facing is that m ...

What could be causing this JS file to not impact the DOM as expected?

Currently, I am delving into the world of JavaScript and trying to gain a better understanding of how to manipulate the DOM on my own. Throughout this learning process, I have encountered a puzzling situation that I am seeking assistance with. The followi ...

What is the best way to save a current HTML element for later use?

Here is a simple HTML code that I would like to save the entire div with the class test_area and then replicate it when needed. Currently, my goal is to duplicate this div and place the clone underneath the original element. How can I achieve this? Unfortu ...

Using conditional logic to check if a column cell is empty

I need help writing a Javascript function that will loop through rows in a table and only change the background color of cells in "column2" if they are empty. My current code is not working as expected, as it colors all rows instead of just those with empt ...

When utilizing the withStyles HOC, innerRef is not included in the passing of other props when passed through React.forwardRef

I have encountered a problem while passing the ref using React.forwardRef to the down component. This method usually works fine. <SomeComponent component={React.forwardRef((props, ref) => <MyComponent innerRef={ref} {...props} />)} .../> Ho ...

The buffer for the operation `users.insertOne()` exceeded the timeout limit of 10000 milliseconds, resulting in a Mongoose

I am currently utilizing a generator that can be found at this Github link Project repository: Github Project Link Encountering an issue when attempting to input a user using the `MASTER_KEY`, I keep receiving the following error message: MongooseError ...

The Intersection Observer API is not compatible with using transform: translateX()

After successfully implementing the Intersection Observer API on my website and incorporating a few transitions from an example I came across, everything seemed to be working smoothly. You can view the scale-in transition in action here: https://jsfiddle.n ...

Error message from Angular development server: Channel is reporting an error in handling the response. The UNK/SW_UNREACHABLE options

After recently installing a new Angular app, I encountered an issue while running 'ng serve'. The application initially loads without any problems, but after a few seconds, I started seeing a strange error in the console. Channel: Error in handle ...

Tips for customizing the appearance of the Alert Dialog in React-admin?

React-admin alert dialog example I'm currently working on a React-admin project and I am looking to customize the alert dialog that displays errors, warnings, and success messages on the page. Specifically, I want to apply CSS styles like z-index and ...

Configuring the default value for a selection menu in Vue3

Obtaining all available categories: const fetchCategories = async () => { let response = await axios.get(`/api/get_all_category/`) categories.value = response.data.categories } The structure of categories.value is shown here: https://i.sstatic.net ...

Incorporate a new item into an array within a JSON `document` using Node.js for every incoming request

I'm facing an issue with storing multiple sets of x, y coordinates in a file on the server side. Currently, when a user right clicks on an image on the frontend, the coordinates are sent to the node server via AJAX post request and saved as objects in ...