How to change only one variable into multiple p tags? My code is not working.
At the beginning, the quantity of the first three products is equal to 10 and the quantity of the fourth product is 5. After pressing the button, the quantity of all products changes to 6. And it should be 11, 11, 11 and 6. The problem is surely in the part of the code responsible for update, i.e. updatedProductsList. I know why it doesn't work properly, but I don't know how to make it work.
class Product {
#count;
constructor(name, count) {
this.name = name;
this.#count = count;
}
getCurrentCount() {
return this.#count;
}
static add() {
products.forEach((item) => {
item.#count ;
return updatedProductsList();
});
}
}
function getProduct(name) {
productCount ;
name = new Product(name, 10);
products.push(name);
}
const printProductsList = () => {
const productsContainer = document.querySelector("div");
document.getElementById("products").innerHTML = `Number of products: ${products.length}`;
products.map((item) => {
const productElement = document.createElement("div");
productElement.innerHTML = `<p>${
item.name
} <span>${item.getCurrentCount()}</span></p>`;
productsContainer.append(productElement);
});
};
const updatedProductsList = () => {
products.map((item) => {
document.querySelectorAll("span").forEach((e) => {
e.innerText = `${item.getCurrentCount()}`;
});
});
};
const products = [];
let productCount = 0;
let apple = getProduct("Apple");
let orange = getProduct("Orange");
let avocado = getProduct("Avocado");
let watermelon = new Product ('Watermelon', 5)
products.push(watermelon)
printProductsList();
<!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" />
<title>Document</title>
<style>
:root {
--bg-color: #ddd;
}
body {
background-color: var(--bg-color);
font-family: sans-serif;
}
div {
margin-top: 3rem;
margin-bottom: 3rem;
}
.product {
background-color: #fff;
}
</style>
<script defer src="script.js"></script>
</head>
<body>
<div >
<h2 id='products'>
`Number of products: ${products}
</h2>
</div>
<button type="button" onclick="Product.add()">Increase the quantity by one</button>
</body>
</html>
CodePudding user response:
The issue is with updatedProductsList. For each product, you're updating every span with the getCurrentCount() in this loop. On the loop's last iteration, it updates all spans with the count of the last item, which is why 6 is written to the page for all products.
const updatedProductsList = () => {
products.map((item) => {
document.querySelectorAll("span").forEach((e) => {
e.innerText = `${item.getCurrentCount()}`;
});
});
};
The underlying data in products has the correct counts as demonstrated by breakpoint debugging or console.log(products); in updatedProductsList. So the fix for this could be to use the index of the span tag to determine which item you're looking at, and then only updating that span:
const updatedProductsList = () => {
document.querySelectorAll("span").forEach((e, index) => {
e.innerText = `${products[index].getCount()}`;
});
};
Note: I also cleaned up some other code in the below snippet. I removed productCount because it wasn't being updated correctly (it was only increasing with getProduct, not products.push(new Product(...))). I also changed getCurrentCount() to getCount() to better fit getter/setter method names (current is implied, as you're always retrieving the current value).
class Product {
count;
constructor(name, count) {
this.name = name;
this.count = count;
}
getCount() {
return this.count;
}
static add() {
products.forEach((item) => {
item.count ;
});
updatedProductsList();
}
}
function getProduct(name) {
name = new Product(name, 10);
products.push(name);
}
const printProductsList = () => {
const productsContainer = document.querySelector("div");
document.getElementById("products").innerHTML = `Number of products: ${products.length}`;
products.map((item) => {
const productElement = document.createElement("div");
productElement.innerHTML = `<p>${
item.name
} <span>${item.getCount()}</span></p>`;
productsContainer.append(productElement);
});
};
const updatedProductsList = () => {
document.querySelectorAll("span").forEach((e, index) => {
e.innerText = `${products[index].getCount()}`;
});
};
const products = [];
products.push(new Product("Apple", 1));
products.push(new Product("Orange", 3));
products.push(new Product("Avocado", 5));
products.push(new Product ('Watermelon', 10));
printProductsList();
<!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" />
<title>Document</title>
<style>
:root {
--bg-color: #ddd;
}
body {
background-color: var(--bg-color);
font-family: sans-serif;
}
div {
margin-top: 3rem;
margin-bottom: 3rem;
}
.product {
background-color: #fff;
}
</style>
<script defer src="script.js"></script>
</head>
<body>
<div >
<h2 id='products'>
`Number of products: ${products}
</h2>
</div>
<button type="button" onclick="Product.add()">Increase the quantity by one</button>
</body>
</html>
