Search code examples
javascriptfunctionlocal-storagee-commercefavorites

function doesnt work, add to favorites E-commerce project


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 drawProductUIfunction 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


Solution

  • 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")
            }
        }
    }