Related
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>
</>
);
}
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"];
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.
I'll explain the why and how of my code. First off, I wanted to make a function that could take any key as an argument. Today we have 'Bags' and 'Shoes', but tomorrow we may have more keys. Therefore, I didn't want to propose a solution that would involve "hard-coded" keys.
Once we have the key, we can use Array.prototype.filter to find the object containing the items we want. In the data we are provided with, 'Bags' and 'Shoes' are keys, not values. Hence why I used product.hasOwnProperty([key]) in the callbackFn. Note the use of the square brackets as we are searching for the value of a dynamic variable named key, not the actual string 'key'. Next we use Array.protoype.flatMap to get to the part of each object that we want, which is the array of items. We use .flapMap here to avoid the nested array that would normally result by chaining filter and map to the data.
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>
</>);
You can use:
a combination of Array.map and Object.keys to get an array with available categories from storeItems object
Array.find to get the products for a given merch category.
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)
I have two arrays in one array item and inside one i only need to show 10 items
my array is like this
this.groupedData = [{
"title": true,
"name": "related",
"list": [{
"id": 30,
"text": "CIGA",
"related": true,
"list": [
]
},
{
"id": 34,
"text": "GAP",
"related": true,
"list": [
]
},
{
"id": 35,
"text": "LEVIS",
"related": true,
"list": [
]
},
{
"id": 36,
"text": "MANGO",
"related": true,
"list": [
]
},
{
"id": 37,
"text": "Nigel",
"related": true,
"list": [
]
},
{
"Id": 39,
"text": "Test",
"related": true,
"list": [
]
}
],
"selected": false,
"disabled": false
},
{
"title": true,
"name": "unrelated",
"list": [{
"id": 29,
"text": "Burger",
"related": false,
"list": [
]
}
],
"selected": false,
"disabled": false
}
]
i am looping list array and need to set only 10 items in one <Ul> tag list items in both arrays and need to loop 10 item list <ul> according to that optionColumnLength has number of columns need to show and that array looks like [0, 1, 2] html is look like this
<div *ngFor="let colindex of optionColumnLength">
<ul class="item2">
<div *ngFor="let group of groupedData let j = index;">
<label>{{group.name}}</label>
<li *ngFor="let item of group.list | slice: colindex * 10: colindex * 10 + 10 | multiSelectFilter:filter; let i = index;" (click)="onItemClick($event,item)" class="multiselect-item-checkbox">
<div class="dd-list-row">
<div class="dd-list-block">
<input type="checkbox" aria-label="multiselect-item" [class.disabled-selected]="disabled"
[checked]="isSelected(item)" [disabled]="disabled || (isLimitSelectionReached() && !isSelected(item)) || item.isDisabled" />
<div>{{item.text}}</div>
</div>
</div>
</li>
<li class='no-data' *ngIf="_data.length == 0">
<h5>{{_settings.noDataAvailablePlaceholderText}}</h5>
</li>
</div>
</ul>
</div>
this is the current view and i only need to show 10 items in one column and if more than that it need to show in another 10 item column
current view image
My data is:
[{
"id": 1,
"label": "List item 1",
"parent_id": 0,
"children": [{
"id": 5,
"label": "List item 1",
"parent_id": 1
},
{
"id": 6,
"label": "List item 1",
"parent_id": 1
},
{
"id": 7,
"label": "List item 1",
"parent_id": 1
},
{
"id": 8,
"label": "List item 1",
"parent_id": 1,
"children": [{
"id": 9,
"label": "List item 1",
"parent_id": 8
},
{
"id": 10,
"label": "List item 1",
"parent_id": 8
}
]
}
]
},
{
"id": 2,
"label": "List item 1",
"parent_id": 0
}
]
My App.js components looks like this:
import React, {useState} from 'react';
import {apiData} from './data/api';
import './App.css';
import {NestedLists} from './components/NestedLists';
const App = () => {
return (
<div className="container">
<h3>Calling a nested component</h3>
<NestedLists filteredData = {data} />
</div>
)
}
export default App;
NestedList component:
import React from 'react'
export const NestedLists = ({filteredData}) => {
return (
<ul>
{filteredData && filteredData.map((m,i) => {
return (
<li key={m.label}>
{m.id}
{m.children && <NestedLists filteredData={m.children} />}
</li>
);
})}
</ul>
)
}
When i check the results there is same nesting printed twice as shown in the below image which should not happen::
Here inside 1: 5,6,7,8 is repeated twice and inside 8 : 9,10 is repeated twice which should not happen. what is missing here?
It is working fine.check where are you making mistake. i have tried this
import React from 'react';
const App = () => {
const data = [{
"id": 1,
"label": "List item 1",
"parent_id": 0,
"children": [{
"id": 5,
"label": "List item 1",
"parent_id": 1
},
{
"id": 6,
"label": "List item 1",
"parent_id": 1
},
{
"id": 7,
"label": "List item 1",
"parent_id": 1
},
{
"id": 8,
"label": "List item 1",
"parent_id": 1,
"children": [{
"id": 9,
"label": "List item 1",
"parent_id": 8
},
{
"id": 10,
"label": "List item 1",
"parent_id": 8
}
]
}
]
},
{
"id": 2,
"label": "List item 1",
"parent_id": 0
}
]
const NestedLists = ({filteredData}) => {
return (
<ul>
{filteredData && filteredData.map((m,i) => {
return (
<li key={m.label}>
{m.id}
{m.children && <NestedLists filteredData={m.children} />}
</li>
);
})}
</ul>
)
}
return (
<div className="container">
<h3>Calling a nested component</h3>
<NestedLists filteredData = {data} />
</div>
)
}
export default App;
I think you are not passing right data here in your App.js file
import {apiData} from './data/api';
<NestedLists filteredData = {data} />
change it to
<NestedLists filteredData = {apiData} />
I have two arrays
{
"products": [
{
"name": "Jivi",
"Hint": "45-60 IE/kg alle 5 Tage\n60 IE 1x/Woche\n30-40 IE 2 x/Woche",
"frequency": ["1", "2", "8"]
},
{
"name": "Adynovi",
"Hint": "40-50 IE/kg 2x/Woche im Abstand von 3-4 Tagen",
"frequency": ["2", "6", "7"]
},
{
"name": "Esperoct",
"Hint": "\"50 IE/kg \nalle 4 Tage\"\n",
"frequency": ["7"]
}
],
"haufigkeit" : [
{
"name": "1x / Woche",
"id": 1,
"value": 52.1428571429
},
{
"name": "2x / Woche",
"value": 104.2857142857143,
"id": 2
}
]
}
I have a select dropdown using Vuejs where the products.name are rendering.
<select v-model="selectFrequency">
<option v-for="(level1,index) in dataJson.products"
v-bind:value="level1.frequency">{{level1.name}}</option>
</select>
For example, When I select Jivi, I would like to compare the numbers in frequency of products with id in haufigkeit and when they matches, then display the name of haufigkeit
Here is what I am trying
computed:{
selectFrequency:function(){
let results= this.haufigkeit.filter(array=>array.every(item => this.products.filter(group=>group.frequency.includes(item))));
}
}
I have been trying for two days and it gives me an error cannot read property 'every' of undefined. Can anyone suggest me where I have done mistake?
Edit: Ok now I understand, something like this should work for you: https://jsfiddle.net/q9grc04s/
If you select a product you will see it displays any haufigkeit that have an ID included in the selected frequency.
<template>
<div>
<div>
<select v-model="selectedFrequency">
<option
v-for="(level1, i) in products"
:key="i"
:value="level1.frequency"
>
{{level1.name}}
</option>
</select>
</div>
<div>
<h1>Haufigkeit Matches:</h1>
<ul v-if="haufigkeitMatches">
<li v-for="match in haufigkeitMatches">{{ match.name }}</li>
</ul>
</div>
</div>
</template>
<script>
export default {
data: {
selectedFrequency: [],
products: [
{
name: "Jivi",
Hint: "45-60 IE/kg alle 5 Tage\n60 IE 1x/Woche\n30-40 IE 2 x/Woche",
frequency: [1, 2, 8]
},
{
name: "Adynovi",
Hint: "40-50 IE/kg 2x/Woche im Abstand von 3-4 Tagen",
frequency: [2, 6, 7]
},
{
name: "Esperoct",
Hint: "\"50 IE/kg \nalle 4 Tage\"\n",
frequency: [7]
}
],
haufigkeit : [
{
name: "1x / Woche",
id: 1,
value: 52.1428571429
},
{
name: "2x / Woche",
value: 104.2857142857143,
id: 2
}
]
},
computed: {
haufigkeitMatches(){
return this.haufigkeit.filter(x => this.selectedFrequency.includes(x.id))
}
}
}
</script>
Note: sorry for all the edits, i'm trying to get to grips with the stackoverflow editor, the JS fiddle link is a working solution though.
You can use Javascript some function. in the below example I'm returning the id's of the haufigkeit array which are equal to the frequencies of the products
var data = {
"products": [
{
"name": "Jivi",
"Hint": "45-60 IE/kg alle 5 Tage\n60 IE 1x/Woche\n30-40 IE 2 x/Woche",
"frequency": ["1", "2", "8"]
},
{
"name": "Adynovi",
"Hint": "40-50 IE/kg 2x/Woche im Abstand von 3-4 Tagen",
"frequency": ["2", "6", "7"]
},
{
"name": "Esperoct",
"Hint": "\"50 IE/kg \nalle 4 Tage\"\n",
"frequency": ["7"]
}
],
"haufigkeit" : [
{
"name": "1x / Woche",
"id": 1,
"value": 52.1428571429
},
{
"name": "2x / Woche",
"value": 104.2857142857143,
"id": 2
}
]
};
var result = [];
function selectFrequency(){
data.products.forEach(elem => {
elem.frequency.forEach(fre =>{
var arr = data.haufigkeit;
if(arr.some(arr => arr.id == fre))
result.push(fre);
})
});
return result;
}
console.log(selectFrequency());
The JSON backend guys provide me its multiple parent child so I have to put the dynamic loop to show parent child.
JSON
"data": [
{
"id": 25,
"slug": "mobiles",
"parent_id": null,
"name": "Mobiles"
},
{
"id": 26,
"slug": "mobile-phones-accessories",
"parent_id": 25,
"name": "Mobile Phones accessories"
},
{
"id": 27,
"slug": "computer-laptop",
"parent_id": null,
"name": "Computer & Laptop"
},
{
"id": 28,
"slug": "laptops",
"parent_id": 27,
"name": "Laptops"
},
{
"id": 29,
"slug": "mobile-phones",
"parent_id": 26,
"name": "Mobiles Phone"
}
]
My Function (Kindly ignore this. It's just a try but I have got 1 child parent)
renderCategoriesHtml() {
const { categories } = this.props;
if (!categories) return false;
const nullCat = [];
categories.map((obj) => {
if (obj.parent_id == null) {
nullCat.push(obj);
}
});
return nullCat.map(
(parentCat, i) => (
<div className="form-group" key={i}>
<div className="checkbox" key={i}>
<label>
<Field
name={`categories.${parentCat.id}`}
component="input"
type="checkbox"
/>
{parentCat.slug}
</label>
</div>
{
categories.map(
(childCat, j) => (
parentCat.id == childCat.parent_id ?
<div className="checkbox ml-20" key={j}>
<label>
<Field
name={`categories.${childCat.id}`}
component="input"
type="checkbox"
/>
{childCat.slug}
</label>
</div>
: ''
)
)
}
</div>
)
);
}
I want this (That dynamic html i want)
<ul>
<li>mobiles</li>
<ul>
<li>mobile-phones-accessories</li>
<ul>
<li>mobile-phones</li>
</ul>
</ul>
<li>computer-laptop</li>
<ul>
<li>laptops</li>
</ul>
</ul>
Try this:
class TreeRender extends React.Component {
state = {
data: JSON.parse('[{"id": 25,"slug": "mobiles","parent_id": null,"name": "Mobiles"},{"id": 26,"slug": "mobile-phones-accessories","parent_id": 25,"name": "Mobile Phones accessories"},{"id": 27,"slug": "computer-laptop","parent_id": null,"name": "Computer & Laptop"},{"id": 28,"slug": "laptops","parent_id": 27,"name": "Laptops"},{"id": 29,"slug": "mobile-phones","parent_id": 26,"name": "Mobiles Phone"}]')
}
getCurrent = (node) => this.state.data.filter(cNode => cNode.parent_id == node).map(cNode => (
<ul key={`node_${cNode.id}`}>
<li>{cNode.name}</li>
{this.getCurrent(cNode.id)}
</ul>
))
render() {
return (
<div>
{this.getCurrent(null)}
</div>
);
}
}
FIDDLE