Structuring and retrieving JSON object (an image) with multiple sizes

Viewed 36

This is how I currently have my JSON data structured:

[
  {
    "slug": "image-1",
    "title": "Image 1",
    "img": "./images/folder1/Image-1.jpg",
    "sizes": [
      {
        "title": "Image 1",
        "size": "Large",
        "price": "$1799",
      },
      {
        "title": "Image 1",
        "size": "Medium",
        "price": "$1299",
      },
      {
        "title": "Image 1",
        "size": "Small",
        "price": "$799",
      }
    ]
  },
  {
    "slug": "image-2",
    ...
    ...
    ...
  }
]

I'm mapping through the sizes and call addToCart(size) when the 'Add' button is clicked.

Template.js:

const details = data.Json
const { addToCart } = useContext(GlobalContext)

// <h1>{details.title}</h1>
// <img src={details.img} />
details.sizes.map((size, index) => {
  return (
    <h2>{size.size}</h2>
    <h2>{size.price}</h2>
    <button onClick={() => addToCart(size)}>
      Add
    </button>
  )
})

GlobalState.js:

function addToCart(cartItem) {
  dispatch({
    type: "ADD_TO_CART",
    payload: cartItem,
  })
}

AppReducer.js:

export default (state, action) => {
  switch (action.type) {
    case "ADD_TO_CART":
      return {
        ...state,
        cartItems: [...state.cartItems, action.payload],
      }

Once the 'Add' button is clicked the following is displayed in the cart:

Title Size Price e.g. Image 1 Medium $1299

CartItem.js:

export const CartItem = ({ cartItem }) => {
  return (
<Item>
  <p>{cartItem.title}</p>
  <p>{cartItem.size}</p>
  <p>{cartItem.price}</p>
</Item>
  )
}

Right now this works; however, I'd like to eliminate the title from each of the sizes so that my JSON data looks like this:

[
  {
    "slug": "image-1",
    "title": "Image 1",
    "img": "./images/folder1/Image-1.jpg",
    "sizes": [
      {
        "size": "Large",
        "price": "$1799",
      },
      {
        "size": "Medium",
        "price": "$1299",
      },
      {
        "size": "Small",
        "price": "$799",
      }
    ]
  },
  {
    "slug": "image-2",
    ...
    ...
    ...
  }
]

How can I go about passing both details.title and size into addToCart()?

1 Answers

You can proxy the in-component-scope details.title value into a new object with the size properties spread in.

// <h1>{details.title}</h1>
// <img src={details.img} />
details.sizes.map((size, index) => {
  return (
    <h2>{size.size}</h2>
    <h2>{size.price}</h2>
    <button
      onClick={() => addToCart({
        title: details.title,
        ...size,
      })}
    >
      Add
    </button>
  )
})
Related