'How to get name of a specific item in array and increment its value
I am working on a simple cart, for a homework project. I would like to ask, what would be the best way to take an item from array and increment its value by one? I have 25 items in the array, and each of them has unique name, so I am not using any IDs. Would it be possible to take these items by their name value?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://kit.fontawesome.com/a2faab1b70.js" crossorigin="anonymous"></script>
<script src="database.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script src="https://unpkg.com/react@17/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script>
<title>Nákupný košík</title>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
let sklad = localStorage.getItem('basket');
basket.push(JSON.parse(sklad));
class Basket extends React.Component {
constructor(props) {
super(props);
this.state = {
counter: basket.length,
basket: basket
};
this.clearCart = () => {
basket = [];
localStorage.setItem("basket", JSON.stringify(basket));
this.setState(basket);
}}
addItem = (a) => { //Here is the problem, how can I increment value of a specific item?
this.setState({[a.target.name]: this.state.counter + 1});
}
removeItem = (a) => { //Here is the problem, how can I decrement value of a specific item?
this.setState({[a.target.name]: this.state.counter - 1})
}
render() {
return <div>
{basket[0]?.map((items) =>
<div>
<div>{items.name}, {this.state.counter}x, Cena {items.price} <button onClick={this.addItem}>+</button> <button onClick={this.removeItem}>-</button></div>
</div>
)}
<div id="counter">Počet položiek v košíku {basket[0]?.length + this.state.counter -1}</div>
<button onClick={this.clearCart} >Vyprázdniť košík</button>
</div>
}
}
ReactDOM.render(
<Basket/>,
document.getElementById('root')
);
</script>
</body>
</html>
//Database with items
let basket = [];
let products = [
{
type: "mb",
name: "Asus Motherboard",
price: "320",
link: "products/asusmb.html",
image: "/Eshop_project/img/asusmb.jfif",
},
{
type: "cpu",
name: "Intel Core i3",
price: "150",
image: "../img/corei3.jfif",
},
{
type: "cpu",
name: "Intel Core i5",
price: "300",
image: "../img/corei5.jfif",
},
{
type: "cpu",
name: "Intel Core i7",
price: "450",
image: "../img/corei7.jfif",
},
{
type: "cpu",
name: "Intel Core i9",
price: "600",
image: "../img/corei9.jfif",
},
{
type: "ram",
name: "Corsair 16gb",
price: "80",
image: "../img/corsair16gb.jfif",
},
{
type: "psu",
name: "Corsair PSU",
price: "100",
image: "../img/corsairpsu.jfif",
},
{
type: "ram",
name: "Crucial 32gb",
price: "160",
image: "../img/crucial32gb.jfif",
},
{
type: "gpu",
name: "Nvidia Geforce RTX3070",
price: "750",
image: "../img/gforce 3070.jfif",
},
{
type: "gpu",
name: "Nvidia Geforce RTX 3080",
price: "950",
image: "../img/gforce_3080.jfif",
},
{
type: "gpu",
name: "Nvidia Geforce RTX 3090",
price: "1200",
image: "../img/gforce_3090.jfif",
},
{
type: "mb",
name: "Gigabyte Motherboard",
price: "400",
image: "../img/gigabytemb.jfif",
},
{
type: "psu",
name: "Gigabyte PSU",
price: "80",
image: "../img/gigabytepsu.jfif",
},
{
type: "ram",
name: "Kingston 16gb",
price: "90",
image: "../img/kingston16gb.jfif",
},
{
type: "mb",
name: "MSI Motherboard",
price: "300",
image: "../img/msimb.jfif",
},
{
type: "case",
name: "Phanteks Case",
price: "70",
image: "../img/Phaktekscase.jfif",
},
{
type: "gpu",
name: "AMD Radeon 6500",
price: "500",
image: "../img/radeon_6500.jfif",
},
{
type: "gpu",
name: "AMD Radeon 6800",
price: "650",
image: "../img/radeon_6800.jfif",
},
{
type: "gpu",
name: "AMD Radeon 6900",
price: "800",
image: "../img/radeon_6900.jfif",
},
{
type: "cpu",
name: "AMD Ryzen 3790",
price: "400",
image: "../img/ryzen3790.jfif",
},
{
type: "cpu",
name: "AMD Ryzen 5600",
price: "550",
image: "../img/ryzen5600.jfif",
},
{
type: "cpu",
name: "AMD Ryzen 5800",
price: "700",
image: "../img/ryzen5800.jfif",
},
{
type: "psu",
name: "Seasonic PSU",
price: "95",
image: "../img/seasonicpsu.jfif",
},
{
type: "case",
name: "Zalmancase",
price: "90",
image: "../img/zalmancase.jfif",
},
{
type: "psu",
name: "Evga PSU",
price: "80",
image: "../img/evgapsu.jfif",
}
]
localStorage.setItem('products', JSON.stringify(products));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
Solution 1:[1]
You can use the uniq name like Id and do something like
const changeInArr = (name, newValue) => {
const newArr = yourArray.map(elem => {
if (name === item.name) {
item.value = newValue
}
return item
}
return newer
}
If you need change different field, you can use a key parameter like that :
const changeInArr = (name, newValue, key) => {
const newArr = yourArray.map(elem => {
if (name === item.name) {
item[key] = newValue
}
return item
}
return newer
}
Say me if work for you
Solution 2:[2]
With the current structure, the only way is to use Array.map.
If you want to optimize it then you need to convert the array to the object.
const products = [
{
type: 'cpu',
name: 'AMD Ryzen 5800',
price: '700',
image: 'img/ryzen5800.jfif'
},
{
type: 'cpu',
name: 'AMD Ryzen 6000',
price: '800',
image: 'img/ryzen6000.jfif'
}
]
const productObj = products.reduce((obj, product) => {
return {
...obj,
[product.name]: product
}
}, {})
console.log(productObj)
console.log(productObj['AMD Ryzen 6000'])
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | LutherW |
| Solution 2 | Krystian Sztadhaus |
