My ArrayList shows empty when looping throug Object.keys - javascript

I am trying to create Simple Table with react.I am importing CustomerList and then looping through all the Object.keys to get the table header first and then the body part.
When console logging I can see all my customerList properties are there but when console.loging the Object.keys it shows 'undefined', I don't understand where I am making the silly mistake.
Will be gratefull for all the help I can get.
Thanks in Advance!
I have tried Google and youtube but not getting the answer I am looking for
export const customerList = [
{
name: "Anny Larsson",
age: 23,
id: 1,
title: "Title1",
accountNumber: "12345",
address: "Stockholm 14, Stockholm Sweden",
hobbyList:["coding", "writing", "reading", "skiing"],
emptyColumn: ""
},
{
name: "Helena hel",
age: 20,
id:2,
title: "Title2",
accountNumber: "22245",
address: "Stockholm City, Stockholm Sweden",
hobbyList:["coding", "Cooking", "games", "skiing"],
emptyColumn: ""
},
{
name: "Ayesha AAA",
age: 25,
id: 3,
title: "Title3",
accountNumber: "09845",
address: "Stockholm 21, Stockholm Sweden",
hobbyList:["coding", "Cooking", "games", "skiing"],
emptyColumn: ""
},
//more list goes here......
// ...............
];
export default customerList;
// My customerListTable.js
import React, { Component } from 'react';
import CustomerList from './CustomerList';
import CustomerTitle from './CustomerTitle';
class CustomerListTable extends Component {
state = {
customerList: CustomerList
}
componentDidMount(){
this.setState({
customerList: [...this.state.customerList] //copying the list
})
};
headerTitle = Object.keys(this.state.customerList[0]).map((header , index) => {
console.log("columnHeaderTitles ", this.headerTitle )
// return (
// <li>{header}</li>
// )
})
render() {
console.log("customer list", this.state.customerList)
console.log("table header", this. headerTitle);
return (
<div>
<h1>Customer table....</h1>
<div>
<CustomerTitle />
<table>
<thead>
<tr>
<th>{this.headerTitle}</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
);
}
}
export default CustomerListTable;

const customerList = [
{
name: "Anny Larsson",
age: 23,
id: 1,
title: "Title1",
accountNumber: "12345",
address: "Stockholm 14, Stockholm Sweden",
hobbyList:["coding", "writing", "reading", "skiing"],
emptyColumn: ""
}
];
const headerTitle = Object.keys(customerList[0]).map((header , index) => header)
console.log(headerTitle)
In Thead Table, map headerTitle to create dynamic th:
<thead>
<tr>
{
this.headerTitle.map((item, index) => <th key={index}>{item}</th>)
}
</tr>
</thead>

I think you are overcomplicating your logic, but your code seems to work.
Only returning something inside your map function adds the headers to the component:
const CustomerList = [
{
name: "Anny Larsson",
age: 23,
id: 1,
title: "Title1",
accountNumber: "12345",
address: "Stockholm 14, Stockholm Sweden",
hobbyList: [
"coding", "writing", "reading", "skiing"
],
emptyColumn: ""
}, {
name: "Helena hel",
age: 20,
id: 2,
title: "Title2",
accountNumber: "22245",
address: "Stockholm City, Stockholm Sweden",
hobbyList: [
"coding", "Cooking", "games", "skiing"
],
emptyColumn: ""
}, {
name: "Ayesha AAA",
age: 25,
id: 3,
title: "Title3",
accountNumber: "09845",
address: "Stockholm 21, Stockholm Sweden",
hobbyList: [
"coding", "Cooking", "games", "skiing"
],
emptyColumn: ""
}
];
class CustomerListTable extends React.Component {
state = {
customerList: CustomerList
}
headerTitle = Object.keys(this.state.customerList[0]).map((header) => {
return (<li key={header}>{header}</li>)
})
render() {
return (<div>
<h1>Customer table....</h1>
<div>
<table>
<thead>
<tr>
<th>{this.headerTitle}</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>);
}
}
ReactDOM.render(<CustomerListTable/>, document.getElementById('root'));
<script crossorigin src="https://unpkg.com/react#16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom#16/umd/react-dom.development.js"></script>
<div id="root"></div>

Related

How to filter array of objects data using multiple tags in react js

const data = [
{ id: 1, name: Mike, city: philps, state: New York },
{ id: 2, name: Steve, city: Square, state: Chicago },
{ id: 3, name: Jhon, city: market, state: New York },
{ id: 4, name: philps, city: booket, state: Texas },
{ id: 5, name: smith, city: brookfield, state: Florida },
{ id: 6, name: Broom, city: old street, state: Florida },
]
const tags = [
{ state: New York },
{ state: Texas },
{ state: Florida },
]
const [tags, setTgas] = useState(tags)
onChange={(e) => {
setTgas([...tags,{state: new_tag},]);
}
how can I get data by filtering using multiple tags? if i remove and add tag data will be displayed accordingly tags and is there is no tag all data will be displayed.
you can use array filter
const data = [
{ id: 1, name: "Mike", city: "philps", state: "New York" },
{ id: 2, name: "Steve", city: "Square", state: "Chicago" },
{ id: 3, name: "Jhon", city: "market", state: "New York" },
{ id: 4, name: "philps", city: "booket", state: "Texas" },
{ id: 5, name: "smith", city: "brookfield", state: "Florida" },
{ id: 6, name: "Broom", city: "old street", state: "Florida" },
]
const tags = [
{ state: "New York" },
{ state: "Texas" },
{ state: "Florida" },
]
const newTags = tags.map(item => item.state)
const newArr = data.filter(item => newTags.includes(item.state))
console.log(newArr)
I hope your logic to add and remove tags is already working as expected. Based on that your requirement can be fulfilled by following:
const data = [{
id: 1,
name: "Mike",
city: "philps",
state: "New York",
},
{
id: 2,
name: "Steve",
city: "Square",
state: "Chicago",
},
{
id: 3,
name: "Jhon",
city: "market",
state: "New York",
},
{
id: 4,
name: "philps",
city: "booket",
state: "Texas",
},
{
id: 5,
name: "smith",
city: "brookfield",
state: "Florida",
},
{
id: 6,
name: "Broom",
city: "old street",
state: "Florida",
},
]
const tags = [{
state: "New York"
},
{
state: "Texas"
},
{
state: "Florida"
},
]
/*
// Your react logic for adding and removing tags
const [tags, setTgas] = useState(tags)
onChange = {
(e) => {
setTgas([...tags, {
state: new_tag
}, ]);
};
*/
// Logic to display data based on filtered tags
const dataToDisplay = tags.length ? data.filter(item => tags.some(tag => tag.state === item.state)) : data;
console.log(dataToDisplay); //This will display all data when the tags is an empty array.
// Get a hook function
const {
useState,
useRef,
useEffect
} = React;
const Example = () => {
const data = [{
id: 1,
name: "Mike",
city: "philps",
state: "New York"
},
{
id: 2,
name: "Steve",
city: "Square",
state: "Chicago"
},
{
id: 3,
name: "Jhon",
city: "market",
state: "New York"
},
{
id: 4,
name: "philps",
city: "booket",
state: "Texas"
},
{
id: 5,
name: "smith",
city: "brookfield",
state: "Florida"
},
{
id: 6,
name: "Broom",
city: "old street",
state: "Florida"
},
];
const [FilteredData, setFilteredData] = useState([]);
const [Tags, setTags] = useState([]);
const selectRef = useRef();
useEffect(() => {
if (Tags.length !== 0) {
setFilteredData(data.filter(item => Tags.includes(item.state)))
} else {
setFilteredData([...data]);
}
}, [Tags]);
const OnAddTag = () => {
if (!Tags.includes(selectRef.current.value)) {
setTags((prev) => [...prev, selectRef.current.value]);
}
};
const OnRemoveTag = () => {
const tags = [...Tags]
const index = tags.indexOf(selectRef.current.value)
if (index > -1) {
tags.splice(tags.indexOf(selectRef.current.value), 1)
}
setTags(tags)
};
const List = FilteredData.map((item) => < li key = {
item.id
} > {
`${item.name} - ${item.state}`
} < /li>);
return ( <
div >
<
div >
<
button onClick = {
OnAddTag
} > Add < /button> <
select ref = {
selectRef
} >
<
option > select < /option> <
option value = {
"New York"
} > New York < /option> <
option value = {
"Texas"
} > Texas < /option> <
option value = {
"Florida"
} > Florida < /option> < /
select >
<
button onClick = {
OnRemoveTag
} > Remove < /button> < /
div >
<
div > Tags = [{
Tags
}] < /div> <
ul > {
List
} < /ul> < /
div >
);
};
// Render it
ReactDOM.createRoot(
document.getElementById("root")
).render( <
Example / >
);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.development.js"></script>

how can I filter a parent object based on the inner (child) object?

As you see in the data below, we have a list of restaurants,
each restaurant has a list of different menus,
and each menu has a list of products
my question is: how can I filter a restaurant based on the product object ?
so as you see the second product object (Typical salad) is missing the price so I want to remove the whole restaurant (Resturant 1) object from data, how can I do it?
const data = [
{
name: "Resturant 1",
phone: "0000555823",
multiple_menus: [
{
name: "salads",
products: [
{
name: "French salad",
price: 15.5
},
{
name: "Typical salad",
}
]
},
{
name: "burgers",
products: [
{
name: "cheese burger",
price: 15.5
},
{
name: "American burger",
price: 10
}
]
},
]
},
{
name: "Resturant 2",
phone: "0000555823",
multiple_menus: [
{
name: "salads",
products: [
{
name: "French salad",
price: 15.5
},
{
name: "Typical salad",
price: 5.5
}
]
}
]
},
]
As a more readable answer, this is a solution
const filteredData = data.filter((restaurant)=>{
const everyMenuProductHasPrice = restaurant.multiple_menus.every((menu)=>{
const everyProductHasPrice = menu.products.every((product)=>!!product.price)
return everyProductHasPrice
})
return everyMenuProductHasPrice
})

Button Id issue

I do have a problem on my code. What I am trying to do, is that when I want to click on a button, I want that this button become "HIDE" (it's show in the beginning), and show the specific Id's information. I tryed to do it with many example but the others buttons change this specific button too. Then, I didn't find the issue. If someone can help me with it. Thank you very much.
import React, { Component } from "react";
import "./IlkOnbir.css";
export default class IlkOnbir extends Component {
state = {
info: false,
btn: true,
players: [
{
id: 1,
name: "Altay Bayindir",
age: "21",
mevki: "Kaleci",
},
{
id: 2,
name: "Serdar Aziz",
age: "29",
mevki: "Stoper",
},
{
id: 3,
name: "Simon Falette",
age: "23",
mevki: "Stoper",
},
{
id: 4,
name: "Nabil Dirar",
age: "33",
mevki: "Sag Bek",
},
{
id: 5,
name: "Hasan Ali Kaldirim",
age: "32",
mevki: "Sol Bek",
},
{
id: 6,
name: "Emre Belözoglu",
age: "37",
mevki: "Orta Saha",
},
{
id: 7,
name: "Luiz Gustavo",
age: "32",
mevki: "Orta Saha",
},
{
id: 8,
name: "Ozan Tufan",
age: "25",
mevki: "Orta Saha",
},
{
id: 9,
name: "Deniz Türüç",
age: "28",
mevki: "Orta Saha",
},
{
id: 10,
name: "Gary Rodriguez",
age: "29",
mevki: "Kanat",
},
{
id: 11,
name: "Tolga Cigerci",
age: "29",
mevki: "Orta Saha",
},
{
id: 12,
name: "Ferdi",
age: "21",
mevki: "Stoper",
},
{
id: 13,
name: "Mevlüt",
age: "33",
mevki: "Stoper",
},
{
id: 14,
name: "Vedat",
age: "26",
mevki: "Stoper",
},
],
}
showInfo = (i) => {
this.setState({ info: !this.state.info});
}
handleClick = event => {
event.currentTarget.classList.toggle('active');
}
btnDisplay = (e) => {
console.log(e.currentTarget.id);
this.setState({info: !this.state.info, btn:!this.state.btn});
}
render() {
const hideInfo = this.state.info;
const pl = this.state.players.map((player,i) => {
return (
<div key={i} className="card--content movie" onClick={this.handleClick}>
<div className="content">
<img src={player.source} alt="" />
<div class="buttons">
<p
onClick={() => this.showInfo(player[i])} key={player[i]} className="btn effect04 movie" data-sm-link-text="INFO"><span>{this.state.btn === true ? "SHOW" : "HIDE"}</span>
</p>
{hideInfo === true ? (
<div className="opening">
<p>{player.name}</p>
<p>{player.age} </p>
<p>{player.mevki} </p>
</div>
) : (
""
)}
</div>
</div>
</div>
)})
return (
<div className="container">
<section className="card">
{pl}
</section>
</div>
)}}
Each player needs its own info property; right now info applies to all of them.
See working example:
https://codesandbox.io/s/sweet-jang-m3yfe?file=/src/App.js
{
id: 1,
name: "Altay Bayindir",
age: "21",
mevki: "Kaleci",
info: false
}
showInfo = i => {
this.setState(state => ({
...state,
players: state.players.map((player, index) =>
index === i ? { ...player, info: !player.info } : player
)
}));
};
onClick={() => this.showInfo(i)}
{player.info && (
<div className="opening">
<p>{player.name}</p>
<p>{player.age} </p>
<p>{player.mevki} </p>
</div>
)}

Rendering an icon if condition is correct

I am trying to render an icon only if collection.masterAssetId === asset.id. I am using a getMaster function to find the collection.masterAssetId. The problem that I am having is that the collectionsarr can be undefined in my getMaster function, but also return a number. I have this error: Uncaught TypeError: Cannot read property 'masterAssetId' of undefined. Would be great if someone could fix this error for me?
Secondly, I am probably making this way too complicated, so feel free to suggest a different approach.
App.js
import React from 'react';
import './App.css';
import {collections} from "./data.js"
import {assets} from "./data.js"
import {FontAwesome, FaStar} from "react-icons/fa"
class App extends React.Component {
constructor() {
super()
this.state = {
collectionsarr: collections,
assetsarr: assets,
clickedassets: []
}
}
getMasterId(assetnr){
const assetnum = ""
if(this.state.collectionsarr.filter(element => element.masterAssetId === assetnr) === undefined){
const assetnum = 0
} else {
const assetnum = this.state.collectionsarr.filter(element => element.masterAssetId === assetnr)[0].masterAssetId
}
return assetnum
}
render(){
return (
<div className="App">
<h1>Sitecore coding challenge</h1>
<div className="left">
{this.state.collectionsarr.map(element =>
<div key={element.id}>
<p onClick={()=>this.handleAssetsClick(element.id)}>{element.name}</p>
<img src={this.getAssetPath(element.masterAssetId)} alt="pic"/>
<br></br>
</div>
)}
</div>
<div className="right">
{this.state.clickedassets.map(asset =>
<div key={asset.id}>
<img src={require(`./${asset.path}`)} alt="pic"/>
<p>{asset.name}</p>
<p>{asset.id}</p>
<button onClick={() => this.makeMaster(asset.id)}>Make master!</button>
<p>icon "this is the master</p>
{asset.id === this.getMasterId(asset.id) && <FaStar />}
<br></br>
</div>
)}
</div>
</div>
)
}
}
export default App
data.js
const collections = [
{
id: 1,
name: "The Simpsons",
masterAssetId: 13,
tags: {
name: "Cartoon",
subTag: {
name: "Simpsons family",
subTag: {
name: "2014",
},
},
},
},
{
id: 2,
name: "Super heroes",
masterAssetId: 24,
tags: {
name: "DC Super heroes",
subTag: {
name: "2014",
},
},
},
{
id: 3,
name: "Toy story",
masterAssetId: 31,
tags: {
name: "Disney",
subTag: {
name: "Pixar",
subTag: {
name: "Original movie",
subTag: {
name: "2010",
},
},
},
},
},
{
id: 4,
name: "Ninjago",
masterAssetId: 42,
tags: {
name: "Ninja",
subTag: {
name: "Secret Ninja Force",
subTag: {
name: "2017",
},
},
},
},
];
const assets = [
{
id: 11,
name: "Homer Simpson",
path: "Homer.jpg",
collectionId: 1,
},
{
id: 12,
name: "Lisa Simpson",
path: "Lisa.jpg",
collectionId: 1,
},
{
id: 13,
name: "Bart Simpson",
path: "Bart.jpg",
collectionId: 1,
},
{
id: 14,
name: "Marge Simpson",
path: "Marge.jpg",
collectionId: 1,
},
{
id: 15,
name: "Grampa Simpson",
path: "Grampa.jpg",
collectionId: 1,
},
{
id: 16,
name: "Maggie Simpson",
path: "Maggie.jpg",
collectionId: 1,
},
{
id: 21,
name: "Green Lantern",
path: "Green lantern.jpg",
collectionId: 2,
}
];
Is the collections data being set properly? What's the console.log() output of the state at render?
At any rate, I think the better approach for setting state is to do it in componentDidMount() lifecycle method:
import {getCollection} from "./data.js";
state = {
collectionsarr: [],
assetsarr: [],
clickedassets: []
},
componentDidMount = () => {
this.setState({
collectionsarr: getCollection()
});
}
data.js:
const collections = [...];
export function getCollection() {
return collections;
}
Change your getMasterId function
showIcon(assetnr) {
let index = (this.state.collectionsarr || []).findIndex(item => {
return item.masterAssetId === assetnr;
})
return index != -1;
}
This function will return true if assetId === masterId then You can render it as
{this.showIcon(asset.id) && <FaStar />}

add and remove item in array on click reactjs

I'm working on a simple table using reactjs and ant design.
My plan is to add and remove a new item on the list on button click.
My problem is I don't know how to do that.
I tried to follow this thread but no luck.
Hope you understand me.
Thanks.
sample code
function remove() {
console.log("remove");
}
function add() {
console.log("add");
}
const columns = [
{
title: "Num",
dataIndex: "num"
},
{
title: "Name",
dataIndex: "name"
},
{
title: "Age",
dataIndex: "age"
},
{
title: "Address",
dataIndex: "address"
}
];
const data = [
{
key: "1",
num: 1,
name: "John Brown",
age: 32,
address: "New York No. 1 Lake Park"
},
{
key: "2",
num: 2,
name: "Jim Green",
age: 42,
address: "London No. 1 Lake Park"
},
{
key: "3",
num: 3,
name: "Joe Black",
age: 32,
address: "Sidney No. 1 Lake Park"
}
];
<Table pagination={false} columns={columns} dataSource={data} />
<Button type="primary" onClick={add}>
add
</Button>
<Button type="danger" onClick={remove}>
remove
</Button>
You need to use react state. State holds the data, when you want to add or remove, update this state and react with re-render the table.
I have updated your code. On click of add a new random row is added. On click of remove last row is removed.
CodeSandbox
import React from "react";
import ReactDOM from "react-dom";
import "antd/dist/antd.css";
import "./index.css";
import { Table, Button } from "antd";
function remove() {
console.log("remove");
}
const columns = [
{
title: "Num",
dataIndex: "num"
},
{
title: "Name",
dataIndex: "name"
},
{
title: "Age",
dataIndex: "age"
},
{
title: "Address",
dataIndex: "address"
}
];
let data = [
{
key: "1",
num: 1,
name: "John Brown",
age: 32,
address: "New York No. 1 Lake Park"
},
{
key: "2",
num: 2,
name: "Jim Green",
age: 42,
address: "London No. 1 Lake Park"
},
{
key: "3",
num: 3,
name: "Joe Black",
age: 32,
address: "Sidney No. 1 Lake Park"
}
];
export default class MyTable extends React.Component {
constructor(props) {
super(props);
this.state = {
data: data
};
}
add = () => {
var row = {
key: "99",
num: 99,
name: "I am New",
age: 32,
address: "New Address"
};
var newStateArray = [...this.state.data];
newStateArray.push(row);
this.setState(() => {
return {
data: newStateArray
};
});
}
remove = () => {
var newStateArray = [...this.state.data];
if(newStateArray.length > 1) {
newStateArray.pop();
}
this.setState(() => {
return {
data: newStateArray
};
});
}
render() {
return (
<div>
<Table
pagination={false}
columns={columns}
dataSource={this.state.data}
/>
<Button type="primary" onClick={this.add}>
add
</Button>
<Button type="danger" onClick={this.remove}>
remove
</Button>
</div>
);
}
}
ReactDOM.render(<MyTable />, document.getElementById("container"));

Categories

Resources