Home > Back-end >  How to Destructure JSON array>object>array
How to Destructure JSON array>object>array

Time:10-23

I'm trying to destructure a JSON file that looks like this:

[
  {
    "Bags": [
      {
        "id": 1,
        "name": "Michael Kors Bag",
        "price": 235,
        "imgURL": "/imgs/03045643da82a42a4a5c86842f4b17f1.jpg"
      },
      {
        "id": 2,
        "name": "Ted Baker Bag",
        "price": 495,
        "imgURL": "/imgs/4c176b2fa86bdcddf74822c2501bbcac.jpg"
      },
      {
        "id": 3,
        "name": "Coach Bag",
        "price": 238,
        "imgURL": "/imgs/coach-jes-crossbody-signature-canvas-brown-black-59181.jpg"
      },
      {
        "id": 4,
        "name": "Kate Spade Bag",
        "price": 35,
        "imgURL": "/imgs/10.jpg"
      }
    ]
  },
  {
    "Shoes": [
      {
        "id": 1,
        "name": "Michael Kors Bag",
        "price": 235,
        "imgURL": "/imgs/03045643da82a42a4a5c86842f4b17f1.jpg"
      },
      {
        "id": 2,
        "name": "Ted Baker Bag",
        "price": 495,
        "imgURL": "/imgs/4c176b2fa86bdcddf74822c2501bbcac.jpg"
      },
      {
        "id": 3,
        "name": "Coach Bag",
        "price": 238,
        "imgURL": "/imgs/coach-jes-crossbody-signature-canvas-brown-black-59181.jpg"
      },
      {
        "id": 4,
        "name": "Kate Spade Bag",
        "price": 35,
        "imgURL": "/imgs/10.jpg"
      }
    ]
  }
]

So that I get the name of the objects ("Bags" and "Shoes").

I'm trying to print out the results on a page based on which is which and I'm feeding in the names as strings to a Store component like so:

<Route path="/store" element={<Store merch="Bags" />} />

This is my Store.tsx file, it doesn't work at all but it's my attempt:

import storeItems from "../data/items.json";
import { Row, Col, Container } from "react-bootstrap";
import { StoreItem } from "../components/StoreItem";
import { useState } from "react";

type StoreProps = {
  merch: string;
};

export function Store({ merch }: StoreProps) {
  const [data, setData] = useState([]);
  for (let i = 0; i < storeItems.length; i  ) {
    let a = Object.values(storeItems[i]);
    console.log(a);
  }
  console.log(storeItems);
  return (
    <>
      <Container className="mw-80 d-flex align-items-center justify-content-center p-0 flex-column mb-5">
        <h1 className="m-5">Bags</h1>
        <Row md={2} xs={1} lg={3} className="g-3">
          {storeItems.map((item) => (
            <Col>
              <StoreItem key={item.id} {...item} />
            </Col>
          ))}
        </Row>
      </Container>
    </>
  );
}

CodePudding user response:

In order to get ["Bags", "Shoes"] from your storeItems you could:

const names = storeItems.flatMap(mi => Object.keys(mi));

This would get additional keys on the same object as well, so if you had:

const storeItems = [
    { "Bags": /*...*/{}, "Bags2": /*...*/{}, },
    { "Shoes": /*...*/{} },
];

then it would return [ "Bags", "Bags2", "Shoes" ]

I have to say, your data is in a pretty strange format, but I answered the question exactly as written

Also, if you want the names of all of the objects in a list, as in the name property of each object you could do something like:

const names = storeItems.flatMap(storeItem =>
    Object
        .values(storeItem)
        .flatMap(itemList => itemList.map(item => item.name))
);

Also, if you want the names of all of the objects in the keys of an object by the name (like "Bags", or "Shoes") then you could:

const names = Object.fromEntries(storeItems.flatMap(storeItem => 
    Object.entries(storeItem)
).map([k,v] => [k,v.map(i => i.name)]))

I'm not quite sure which one of these you wanted, so I included all of them (:

Edit

Looking at your code it seems as if you want to get a specific section of the data. This could be done by something like this:

const name = "Shoes";
const items = storeItems.flatMap(si => Object.entries(si))[name]

or if you know that your data is going to always have shoes first and be in the exact format then you could just do

const name = "Shoes";
const items = storeItems[1]["Shoes"];

CodePudding user response:

Is this what you're trying to do?

const products = [
  {
    "Bags": [
      {
        "id": 1,
        "name": "Michael Kors Bag",
        "price": 235,
        "imgURL": "/imgs/03045643da82a42a4a5c86842f4b17f1.jpg"
      },
      {
        "id": 2,
        "name": "Ted Baker Bag",
        "price": 495,
        "imgURL": "/imgs/4c176b2fa86bdcddf74822c2501bbcac.jpg"
      },
      {
        "id": 3,
        "name": "Coach Bag",
        "price": 238,
        "imgURL": "/imgs/coach-jes-crossbody-signature-canvas-brown-black-59181.jpg"
      },
      {
        "id": 4,
        "name": "Kate Spade Bag",
        "price": 35,
        "imgURL": "/imgs/10.jpg"
      }
    ]
  },
  {
    "Shoes": [
      {
        "id": 1,
        "name": "Michael Kors Bag",
        "price": 235,
        "imgURL": "/imgs/03045643da82a42a4a5c86842f4b17f1.jpg"
      },
      {
        "id": 2,
        "name": "Ted Baker Bag",
        "price": 495,
        "imgURL": "/imgs/4c176b2fa86bdcddf74822c2501bbcac.jpg"
      },
      {
        "id": 3,
        "name": "Coach Bag",
        "price": 238,
        "imgURL": "/imgs/coach-jes-crossbody-signature-canvas-brown-black-59181.jpg"
      },
      {
        "id": 4,
        "name": "Kate Spade Bag",
        "price": 35,
        "imgURL": "/imgs/10.jpg"
      }
    ]
  }
]

const getProductsByKey = key => products
    .filter(product => product.hasOwnProperty([key]))
    .flatMap(obj => obj[key])

console.log(getProductsByKey('Shoes'))

The output of the above code would be:

[
  {
    id: 1,
    name: 'Michael Kors Bag',
    price: 235,
    imgURL: '/imgs/03045643da82a42a4a5c86842f4b17f1.jpg'
  },
  {
    id: 2,
    name: 'Ted Baker Bag',
    price: 495,
    imgURL: '/imgs/4c176b2fa86bdcddf74822c2501bbcac.jpg'
  },
  {
    id: 3,
    name: 'Coach Bag',
    price: 238,
    imgURL: '/imgs/coach-jes-crossbody-signature-canvas-brown-black-59181.jpg'
  },
  { id: 4, name: 'Kate Spade Bag', price: 35, imgURL: '/imgs/10.jpg' }
]

Please note that the supplied data is incorrect as the items under the key "Shoes" are apparently bags.

CodePudding user response:

For getting the shoes you can use this:

storeItems[1]["shoes"]

And for getting the bags you can use this:

storeItems[0]["bags"]

So, in the return expression in your attempt code, instead of this:

return (
<>
  <Container className="mw-80 d-flex align-items-center justify-content-center p-0 flex-column mb-5">
    <h1 className="m-5">Bags</h1>
    <Row md={2} xs={1} lg={3} className="g-3">
      {storeItems.map((item) => (
        <Col>
          <StoreItem key={item.id} {...item} />
        </Col>
      ))}
    </Row>
  </Container>
</>);

use this (for bags):

return (
<>
  <Container className="mw-80 d-flex align-items-center justify-content-center p-0 flex-column mb-5">
    <h1 className="m-5">Bags</h1>
    <Row md={2} xs={1} lg={3} className="g-3">
      {storeItems[0]["bags"].map((item) => (
        <Col>
          <StoreItem key={item.id} {...item} />
        </Col>
      ))}
    </Row>
  </Container>
</>);

CodePudding user response:

const storeItems = [
  {
    "Bags": [
      {
        "id": 1,
        "name": "Michael Kors Bag",
        "price": 235,
        "imgURL": "/imgs/03045643da82a42a4a5c86842f4b17f1.jpg"
      },
      {
        "id": 2,
        "name": "Ted Baker Bag",
        "price": 495,
        "imgURL": "/imgs/4c176b2fa86bdcddf74822c2501bbcac.jpg"
      },
      {
        "id": 3,
        "name": "Coach Bag",
        "price": 238,
        "imgURL": "/imgs/coach-jes-crossbody-signature-canvas-brown-black-59181.jpg"
      },
      {
        "id": 4,
        "name": "Kate Spade Bag",
        "price": 35,
        "imgURL": "/imgs/10.jpg"
      }
    ]
  },
  {
    "Shoes": [
      {
        "id": 1,
        "name": "Michael Kors Bag",
        "price": 235,
        "imgURL": "/imgs/03045643da82a42a4a5c86842f4b17f1.jpg"
      },
      {
        "id": 2,
        "name": "Ted Baker Bag",
        "price": 495,
        "imgURL": "/imgs/4c176b2fa86bdcddf74822c2501bbcac.jpg"
      },
      {
        "id": 3,
        "name": "Coach Bag",
        "price": 238,
        "imgURL": "/imgs/coach-jes-crossbody-signature-canvas-brown-black-59181.jpg"
      },
      {
        "id": 4,
        "name": "Kate Spade Bag",
        "price": 35,
        "imgURL": "/imgs/10.jpg"
      }
    ]
  }
]


// Get the values for merch types
const categories = storeItems.map((entry) => Object.keys(entry)[0])
console.log(categories)

// Find the products for a given merch
const merch = 'Shoes'
const products = storeItems.find((entry) => entry[merch])[merch]
console.log(products)

  • Related