what I need to do is when I click on the heartBtn
it turns red and add the item to an array of objects in the localstorage productsInFavArr
and when I click again it should turns grey and remove the object from productsInFavArr
.
the adding function is working perfectly in added the item to the arr part but the drawProductUI
function supposed to check if the product exist in the productsInFacArr
the btn will be red and if not its gonna be grey, so i put the drawProductUI
function in the adding and removing function after adding and removing the item but it doesnt work till I reload the page
and the removing function remove the object from the arr after two click and still doesnt change colot of the btn
so my main problem is changing the color of the btn after adding or removing the item and the removing function remove the item after two clicks
here is the code:
// Draw Product UI
function drawProductUI(array){
var productsUI = array.map((item) => {
if (productsInFavArr) {
for (const favProd of productsInFavArr){
if (favProd.id === item.id) {
// console.log(favProd);
return `
<div class="product-item">
<div class="product-img-container">
<img src=${item.imgURL} alt="products" class="product-img" width="100%" height="150px">
</div>
<div class="product-text">
<h2 class="product-title">${item.title}</h2>
<span class="product-desc">${item.desc}</span>
<p class="product-price">USD ${item.price}</p>
</div>
<div class="product-btns">
<button class="add-to-cart">Add To Cart</button>
<button class="heart-btn heart-icon-red" onclick="removeItemFromFav( ${item.id} )"><i class="far fa-heart"></i></button>
</div>
</div>
`;
}
}}
return`
<div class="product-item">
<div class="product-img-container">
<img src=${item.imgURL} alt="products" class="product-img" width="100%" height="150px">
</div>
<div class="product-text">
<h2 class="product-title">${item.title}</h2>
<span class="product-desc">${item.desc}</span>
<p class="product-price">USD ${item.price}</p>
</div>
<div class="product-btns">
<button class="add-to-cart">Add To Cart</button>
<button class="heart-btn heart-icon" ><i class="far fa-heart"></i></button>
</div>
</div>
`
});
productsContainer.innerHTML = productsUI.join("");
}
drawProductUI(allProducts)
// add to favorites
for(let f=0; f < heartBtn.length; f++){
heartBtn[f].addEventListener("click" ,()=>{
addToFavorites(allProducts[f]);
function addToFavorites(product){
if (localStorage.getItem("userValidate") && localStorage.getItem("passValidate")) {
let productsInFavObj = localStorage.getItem("productsInFavObj");
productsInFavObj = JSON.parse(productsInFavObj);
if(productsInFavObj != null){
if(productsInFavObj[product.id] == undefined){
productsInFavObj = {
...productsInFavObj,
[product.id] : product
}
}
}else{
productsInFavObj = {
[product.id] : product
}
}
let productsInFavArr = Object.values(productsInFavObj)
localStorage.setItem("productsInFavArr" , JSON.stringify(productsInFavArr) )
localStorage.setItem("productsInFavObj" , JSON.stringify(productsInFavObj) )
}else{
window.location.href = "login.html";
}
}
drawProductUI(allProducts)
})
}
// Remove From Favorite
function removeItemFromFav(id){
for(let f=0; f < heartBtn.length; f++){
let productsInFavArr = localStorage.getItem("productsInFavArr")
if(productsInFavArr){
let items = JSON.parse(productsInFavArr);
console.log("removed item:",allProducts[f]);
let filteredItems = items.filter((item) => item.id !== id);
localStorage.setItem("productsInFavArr" , JSON.stringify(filteredItems));
localStorage.setItem("productsInFavObj" , JSON.stringify(filteredItems) )
drawProductUI(allProducts)
console.log(filteredItems);
if(filteredItems.length==0){
localStorage.removeItem("productsInFavArr")
localStorage.removeItem("productsInFavObj")
}
}
}
}
and here is an example of the products
let products = [
{
title: "Sunglasses",
imgURL: "images/Products/sunglasses.jpg",
desc: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Aut nulla adipisci fugiat pariatur recusandae repudiandae fuga molestias doloremque itaque obcaecati.",
price:80,
id: 1
},
{
title: "Laptop",
imgURL: "images/Products/laptop.jpg",
desc: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Aut nulla adipisci fugiat pariatur recusandae repudiandae fuga molestias doloremque itaque obcaecati.",
price:100,
id: 2
},
{
title: "Microphone",
imgURL: "images/Products/mic.jpg",
desc: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Aut nulla adipisci fugiat pariatur recusandae repudiandae fuga molestias doloremque itaque obcaecati.",
price:75,
id: 3
},
{
title: "Cat",
imgURL: "images/Products/cat.jpg",
desc: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Aut nulla adipisci fugiat pariatur recusandae repudiandae fuga molestias doloremque itaque obcaecati.",
price:200,
id: 4
},
]
thanks
In the drawProductUI
function you are not reading local storage value, but it depends on productsInFavArr
which is probably only reading the local storage value ONCE. I think you need to grab the fresh value whenever you call drawProductUI in order to reflect changes made to local storage without reloading the page.
function drawProductUI(array){
let productsInFavArr = JSON.parse(localStorage.getItem("productsInFavArr")) || []; // read the value here so it's fresh before redraw happens
var productsUI = array.map((item) => {
// rest of the function code
In the drawProductUI
function you define handler for selected items:
<button class="heart-btn heart-icon-red" onclick="removeItemFromFav(${item.id})">
<i class="far fa-heart"></i>
</button>
You should do the same for the unselected button version:
<button class="heart-btn heart-icon" onclick="addToFavorites(${item.id})">
<i class="far fa-heart"></i>
</button>
this way the click handler will be attached every time you redraw the UI not only once when the js file is being read, which is the case when you define the handler as you currently do.
Having this in place you need to define the addToFavorites
function at the top level, so outside of the loop, just as you define removeItemFromFav
.
Since the handler takes id of the product now, you need to find the appropriate product before processing it.
You also want to redraw the UI when this is clicked so add the appropriate method to the bottom of the function.
I've attached comments indicating those changes:
function addToFavorites(id){ // this is now defined at the top level as removeItemFromFav
if (localStorage.getItem("userValidate") && localStorage.getItem("passValidate")) {
const product = allProducts.find(p => p.id == id); // this and next lines handle product lookup
if (!product) { return; }
let productsInFavObj = localStorage.getItem("productsInFavObj");
productsInFavObj = JSON.parse(productsInFavObj);
if(productsInFavObj != null){
if(productsInFavObj[id] == undefined){
productsInFavObj = {
...productsInFavObj,
[id] : product
}
}
}else{
productsInFavObj = {
[id] : product
}
}
let productsInFavArr = Object.values(productsInFavObj)
localStorage.setItem("productsInFavArr" , JSON.stringify(productsInFavArr) )
localStorage.setItem("productsInFavObj" , JSON.stringify(productsInFavObj) )
drawProductUI(allProducts); // this redraws the UI
}else{
window.location.href = "login.html";
}
}
Last thing you want to correct is the removeItemFromFav
function.
Loop is unnecessary
function removeItemFromFav(id){
// loop is gone now, also console.logs are gone
let productsInFavArr = localStorage.getItem("productsInFavArr")
if(productsInFavArr){
let items = JSON.parse(productsInFavArr);
let filteredItems = items.filter((item) => item.id !== id);
localStorage.setItem("productsInFavArr" , JSON.stringify(filteredItems));
localStorage.setItem("productsInFavObj" , JSON.stringify(filteredItems) )
drawProductUI(allProducts)
if(filteredItems.length==0){
localStorage.removeItem("productsInFavArr")
localStorage.removeItem("productsInFavObj")
}
}
}