Display array list of object in React JS - javascript

Hi I have this list array of object in react js and I don't know how to display in my render view. Anyone can give an idea on how to do it?
Post:{
Store1: [
0:{Id:"0001", Business:"Ministop"}
]
Store2: [{
0:{Id:"0002", Business:"Grocery Store"}
}]
Store3: [
0:{Id:"0003", Business:"Seven Eleven"}
]
Store4: [
0:{Id:"0004", Business:"Big Store"},
1:{Id:"0005", Business:"Medium Store"}
]
}
This is the sample output:
**Store 1**
**Id Business**
0001 Ministop
**Store 2**
**Id Business**
0002 Grocery Store
**Store 3**
**Id Business**
0003 Seven Eleven
**Store 4**
**Id Business**
0004 Big Store
0005 Medium Store
I have this code and I've got an error this.state.post.map is not a function
render() {
const groupList = this.state.post.map((data, index) => {
return (
<div key={index}>
<div>{data}</div>
</div>
)
});
return (
<div>{groupList}</div>
)
}
Thank you

This is how you map it. just change post with this.state.post
const post = {
Store1: [
{ Id: '0001', Business: 'Ministop' }
],
Store2: [
{ Id: '0002', Business: 'Grocery Store' }
],
Store3: [
{ Id: '0003', Business: 'Seven Eleven' }
],
Store4: [
{ Id: '0004', Business: 'Big Store' },
{ Id: '0005', Business: 'Medium Store' }
]
};
console.log(Object.keys(post).reduce((acccumilator, iterator) => {
return [...acccumilator, ...post[iterator]];
}, []));
/*
Object.keys(this.state.post).reduce((acccumilator, iterator) => {
return [...acccumilator, ...post[iterator]];
}, []).map(data => {
return (
<div key={data.id}>
<div>{data.Business}</div>
</div>
)
})
*/

map is not a method of an object. You can map over its keys using Object.keys.
render() {
const groupList = Object.keys(this.state.post).map((key) => {
return (
<div key={key}>
<div>{this.state.post[key]}</div>
</div>
)
});
return (
<div>{groupList}</div>
)
}
However, there are other problems once you fix that but you should try to solve them yourself and ask other questions if you can't

Related

How to iterate json object field in react

There is a JSON for categories with the following structure
[
{
"category": "Mobiles",
"sub": [
{
"name": "Apple"
},
{
"name": "Samsung"
}
]
},
{
"category": "Televisions",
"sub": [
{
"name": "Lg"
},
{
"name": "Sony"
}
]
}
]
First i load data from backend to a variable called categories (On the backend side im using expressjs and pass data with res.json(JSON.parse(fs.readFileSync('categories.json')))
I want to iterate through categories sub category with
{categories.map(function (category, i) {
return (
<>
<h6 Key={i}>{category.category}</h6> //For example: <h6>Mobiles</h6>
<>... [logic to iterate the current category's sub categories] ...</> //For example: <p>Apple</p> <p>Samsung</p>
</>
);
})}
I tried to use a second map on category.sub like category.sub.map((s,j)=><p Key={j}>{s.name}</p>) but unfortunely i can't get it work, and I can't describe my problem to Google in English so it can be an easy answer and i am the big L
Any help?
Thanks
Try this, uncomment out the console.log to verify data if screen is white.
return (
<>
{categories.map(function (category, i) {
// console.log(category.category );
// console.log(category.sub );
return (
<>
<h6 key={i}>{category.category}</h6>
<>
{category.sub.map(function (sub, j) {
// console.log(category.category + '' + sub.name);
return <p key={j}> {sub.name}</p>;
})}
</>
</>
);
})}
</>
);
Data:
let categories = [
{
category: 'Mobiles',
sub: [
{
name: 'Apple',
},
{
name: 'Samsung',
},
],
},
{
category: 'Televisions',
sub: [
{
name: 'Lg',
},
{
name: 'Sony',
},
],
},
];

Join multiple array maps in ReactJs

im new in reactjs, is that possible to do in reactjs,like mysql inner join, here my sample code.
{dataCustomer.map((customer) => (
<tr>
<td>{customer.custid}</td>
<td>{customer.custname}</td>
<td>{customer.mailingaddr}</td>
<td>{customer.stateid}</td>
<td>{customer.districtid}</td>
<td>{customer.postcode}</td>
</tr>
))}
{dataState.map((state) => (
<tr>
<td>{state.stateid}</td>
<td>{state.statename}</td>
</tr>
))}
how to join array map data from customer.stateid & state.stateid to call state.statename without use SQL syntax?..Is that possible?
This should work
let joinedData=[]
dataCustomer.forEach((customer)=>{
let st= dataState.filter((state)=>state.stateid===customer.stateid);
if(st.length>0)
joinedData.push({...customer,statename:st[0].statename})
})
joinedData array will now contain the customer objects with the corresponding statename and you can use it as
{joinedData.map((customer) => (
<tr>
<td>{customer.custid}</td>
<td>{customer.custname}</td>
<td>{customer.mailingaddr}</td>
<td>{customer.stateid}</td>
<td>{customer.districtid}</td>
<td>{customer.postcode}</td>
<td>{customer.statename}</td>
</tr>
))}
It is not exactly the same but I think the function below that I wrote can help you:
let customers = [{
name: "Foo",
stateid: 1
},
{
name: "Boo",
stateid: 3
},
{
name: "Goo",
stateid: 2
},
{
name: "Zoo",
stateid: 2
},
];
let states = [{
name: "State1",
id: 1
},
{
name: "State2",
id: 2
},
];
function join(customers, states, column1, column2) {
return customers.map(customer => {
states.forEach(state => {
if (customer[column1] === state[column2]) {
customer["state"] = { ...state };
}
})
return customer;
})
}
console.log(join(customers, states, "stateid", "id"))
Note that column1 and column2 parameters are the properties you are joining on.

Loop inside loop in redux store

I have a simple state:
const INITIAL_PEOPLE = {
name: 'Friends',
list: [
{
id: 1,
name: 'Alexander',
child: [
{
id: 2,
name: 'Romuald'
},
{
id: 3,
name: 'Vanessa'
}
]
},
{
id: 4,
name: 'Alex',
child: [
{
id: 5,
name: 'Jessica'
}
]
}
]
}
Now I want to print that. Look at my code
{prople.list.map(person =>
<li key={person.id}>{person.name}
{person.child.map(child =>
{child.name}
)}
</li>
)}
First loop works correctly but if I added second loop (child), console catch an error that person.child is undefined. Why it doesn't work?
You were not returning any value from your map function.
{INITIAL_PEOPLE.list.map((person) => {
return (
<li key={person.id}>
{person.name}
{person.child.map((child) => {
return child.name;
})}
</li>
);
})}
Your code should be written like this with a check if person have a child array.
{prople.list.map(person =>
<li key={person.id}>{person.name}
{person.child && person.child.length && person.child.map(child =>
{return child.name }
)}
</li>
)}
Here before calling the map function for child, we are checking if person has an attribute named child and if child is an array by checking if child has a property length by person.child.length. Notice the return part in the nested map.

Issues with an object- Will not map

Whenever I run my React program, I receive the following error:
Objects are not valid as a React child (found: object with keys {mappedCats}). If you meant to render a collection of children, use an array instead.
in choicesList (at App.js:33)
What I am trying to do is take the FEATURES object, iterate through it and create a div for each category. Then iterate through the items of that category to show the name and cost of each item. I tried converting the object to an array, but it doesn't seem to be working. Originally I tried splitting this up into multiple components but I think I was overly ambitious.
The Categories component just takes the props and puts them into a div and paragraphs.
If somebody could point out my mistake I would appreciate it. Thank You
import React from 'react'
import Categories from './categories'
const choicesList = (props) => {
const FEATURES = {
Processor: [
{
name: '17th Generation Intel Core HB (7 Core with donut spare)',
cost: 700
},
{
name: 'Professor X AMD Fire Breather with sidewinder technology',
cost: 1200
}
],
"Operating System": [
{
name: 'Ubuntu Linux 16.04',
cost: 200
},
{
name: 'Bodhi Linux',
cost: 300
}
],
"Video Card": [
{
name: 'Toyota Corolla 1.5v',
cost: 1150.98
},
{
name: 'Mind mild breeze 2000',
cost: 1345
}
],
Display: [
{
name: '15.6" UHD (3840 x 2160) 60Hz Bright Lights and Knobs',
cost: 1500
},
{
name: '15.3" HGTV (3840 x 2160) Home makeover edition',
cost: 1400
},
]
};
const mappedCats = Object.keys(FEATURES).map((cat) => {
return (
<div>
<h1>{cat}</h1>
{Object.keys(FEATURES[cat]).map((item, idx) => {
return (
<Categories name={FEATURES[cat][idx].name} cost={FEATURES[cat][idx].cost}/>
)
})}
</div>
)
})
return(
{mappedCats}
)
}
export default choicesList
Because React components must render a single root element, you'd need to wrap it in either a fragment or an element:
return (
<>{ mappedCats }</>
)
As raw js (not enclosed in markup) your render method is returning an object literal:
// this is shorthand for { mappedCats: mappedCats }
return { mappedCats };
mappedCats itself is a valid element(s). Just return that
return mappedCats
const ChoicesList = (props) => {
const FEATURES = {
Processor: [
{
name: "17th Generation Intel Core HB (7 Core with donut spare)",
cost: 700,
},
{
name: "Professor X AMD Fire Breather with sidewinder technology",
cost: 1200,
},
],
"Operating System": [
{
name: "Ubuntu Linux 16.04",
cost: 200,
},
{
name: "Bodhi Linux",
cost: 300,
},
],
"Video Card": [
{
name: "Toyota Corolla 1.5v",
cost: 1150.98,
},
{
name: "Mind mild breeze 2000",
cost: 1345,
},
],
Display: [
{
name: '15.6" UHD (3840 x 2160) 60Hz Bright Lights and Knobs',
cost: 1500,
},
{
name: '15.3" HGTV (3840 x 2160) Home makeover edition',
cost: 1400,
},
],
};
const mappedCats = Object.keys(FEATURES).map((cat) => {
return (
<div>
<h1>{cat}</h1>
{Object.keys(FEATURES[cat]).map((item, idx) => {
return (
<div>
{`name: ${FEATURES[cat][idx].name}`}
<br></br>
{`cost: ${FEATURES[cat][idx].cost}`}
</div>
);
})}
</div>
);
});
return mappedCats;
//return (<div>{ mappedCats }</div>);
};
const domContainer = document.querySelector('#app');
ReactDOM.render(<ChoicesList />, domContainer);
<script crossorigin src="https://unpkg.com/react#16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom#16/umd/react-dom.production.min.js"></script>
<div id="app"> </div>

React mapping menu from JSON

I have a scrolling menu items, and the titles of each item is hardcoded into a const, along side with the id
const list = [
{ name: "category1", id: 0 },
{ name: "category2", id: 1 },
{ name: "category3", id: 2 },
{ name: "category4", id: 3 },
{ name: "category5", id: 4 },
{ name: "category6", id: 5 },
{ name: "category7", id: 6 },
{ name: "category8", id: 7 }
];
I have a json file that contains the category name for each child:
{
"results": [
{
"category": "category1",
"name": {
"title": "mr",
"first": "ernesto",
"last": "roman"
},
"email": "ernesto.roman#example.com",
"id": {
"name": "DNI",
"value": "73164596-W"
},
"picture": {
"large": "https://randomuser.me/api/portraits/men/73.jpg",
"medium": "https://randomuser.me/api/portraits/med/men/73.jpg",
"thumbnail": "https://randomuser.me/api/portraits/thumb/men/73.jpg"
}
},
{
"category": "category2",
"name": {
"title": "mr",
"first": "adalbert",
"last": "bausch"
},
"email": "adalbert.bausch#example.com",
"id": {
"name": "",
"value": null
} etc....
I want to show these categories "category": "category1", as the titles of my menu, I now that I need to start stateless and add them from the JSON, the fetching part from the JSON is done locally in componentDidMount, but I am not sure how can I map them into appearing as menu names to make the menu dynamic, I basically want the same output but from the json not hardcoded. here is a sandbox snippet, would appreciate the help.
https://codesandbox.io/s/2prw4j729p?fontsize=14&moduleview=1
Just convert the JSON output to an object like list with a map function from the results and then set is as MenuItems on the state, which is what you pass to the function on render(). Like that.
import React, { Component } from "react";
import ScrollMenu from "react-horizontal-scrolling-menu";
import "./menu.css";
// One item component
// selected prop will be passed
const MenuItem = ({ text, selected }) => {
return (
<div>
<div className="menu-item">{text}</div>
</div>
);
};
// All items component
// Important! add unique key
export const Menu = list =>
list.map(el => {
const { name, id } = el;
return <MenuItem text={name} key={id} />;
});
const Arrow = ({ text, className }) => {
return <div className={className}>{text}</div>;
};
export class Menucat extends Component {
state = {
selected: "0",
MenuItems: []
};
componentDidMount() {
fetch("menu.json")
.then(res => res.json())
.then(result => {
const items = result.results.map((el, idx) => {
return { name: el.category, id: idx };
});
this.setState({
isLoaded: true,
MenuItems: items
});
});
}
render() {
const { selected, MenuItems } = this.state;
// Create menu from items
const menu = Menu(MenuItems, selected);
return (
<div className="App">
<ScrollMenu
data={menu}
selected={selected}
onSelect={this.onSelect}
alignCenter={true}
tabindex="0"
/>
</div>
);
}
}
export default Menucat;
Cheers!
Looks like you don't have to hard code your category list at all. In your componentDidMount() fetch the json and group the results into separate categories like this:
const json = {
"results": [
{
category: "category1",
name: "Fred"
},
{
category: "category1",
name: "Teddy"
},
{
category: "category2",
name: "Gilbert"
},
{
category: "category3",
name: "Foxy"
},
]
}
const grouped = json.results.reduce((acc, cur) => {
if (!acc.hasOwnProperty(cur.category)) {
acc[cur.category] = []
}
acc[cur.category].push(cur)
return acc;
}, { })
// parent object now has 3 properties, namely category1, category2 and category3
console.log(JSON.stringify(grouped, null, 4))
// each of these properties is an array of bjects of same category
console.log(JSON.stringify(grouped.category1, null, 4))
console.log(JSON.stringify(grouped.category2, null, 4))
console.log(JSON.stringify(grouped.category3, null, 4))
Note that this json has 4 objects in result array, 2 of cat1, and 1 of cat 2 and cat3. You can run this code in a separate file to see how it works. Ofcourse you will be fetching the json object from server. I just set it for demonstration.
Then set teh state:
this.setState({ grouped })
Then in render() you only show the categories that have items like:
const menuBarButtons = Object.keys(this.state.grouped).map((category) => {
/* your jsx here */
return <MenuItem text={category} key={category} onClick={this.onClick} blah={blah}/>
/* or something , it's up to you */
})
I'm assuming you're showing the items based on the currently selected category this.state.selected. So after you have rendered your menu, you would do something like:
const selectedCatItems = this.state.grouped[this.state.selected].map((item) => {
return <YourItem name={item.name} key={item.id} blah={blah} />
})
Then render it:
return (
<div className="app">
<MenuBar blah={blah}>
{menuBarButtons}
</Menubar>
<div for your item showing area>
{selectedCatItems}
</div>
</div>
)
Also, don't forget to change your onClick() so that it sets this.state.selected state properly. I believe you can figure that out yourself.
Hope it helps.
PS: I didn't write a whole copy/paste solution to your problem simply because I'm reluctant to read and understand your UI details and the whole component to component data passing details..

Categories