Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Javascript: Spread array of an object in an object and change properties inside it only

I have a scenario where I want to change properties of object in an array. That array is wrapped inside another object.


const defaultData = {
  title: "Title",
  subtitle: "Subtitle",
  books: [
    {
      bookId: "1",
      imageSrc:
        "any.png",
      name: "Issue",
      userOwnsData: true,
      panelsCollected: 0,
      totalPanels: 123,
      link: "https://google.com",
    },
  ],
  bgColor: "black",
};

When I spread it like this:

{...defaultData, ...defaultData.books[0], panelsCollected:123} //previously it was 0

then it adds another extra object to parent object but not update it inside first index of books array

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

How can I just change that panelsCollected property without disturbing whole structure as we are using typescript.

Thanks

>Solution :

When spreading an object with nested properties with the intention of updating specific properties, think of it in two steps:

  1. Spread the original object to copy it (...)
  2. Redefine the new property values after the spread object

In your example we are doing the following:

  • Duplicating defaultData and assigning an updated books property (to be defined in the next step)
  • Duplicating the first book (defaultData.books[0]) and assigning an updated panelsCollected property to it. Then overwriting the existing books property with this updated array item

The result is as follows:

const defaultData = {
  title: "Title",
  subtitle: "Subtitle",
  books: [
    {
      bookId: "1",
      imageSrc:
        "any.png",
      name: "Issue",
      userOwnsData: true,
      panelsCollected: 0,
      totalPanels: 123,
      link: "https://google.com",
    },
  ],
  bgColor: "black",
};

const newBook = {
  ...defaultData,
  books: [
    {
      ...defaultData.books[0],
      panelsCollected: 123
    }
  ]
}

console.log(newBook)
/*
{
  title: "Title",
  subtitle: "Subtitle",
  books: [
    {
      bookId: "1",
      imageSrc:
        "any.png",
      name: "Issue",
      userOwnsData: true,
      panelsCollected: 123,
      totalPanels: 123,
      link: "https://google.com",
    },
  ],
  bgColor: "black",
};
*/

If for example the books property was 1000 items long, you would instead use have to find the specific book in your array using an array method (e.g. find / findIndex) and update it, e.g.

const bookToUpdateIndex = defaultData.books.findIndex(book => bookId === '1')

const updatedBooks = defaultData.books
updatedBooks[bookToUpdateIndex] = {
  ...updatedBooks[bookToUpdateIndex],
  panelsCollected: 123
}

const newBook = {
  ...defaultData,
  books: updatedBooks
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading