0

The problem is I can't control the filter remember I have 20 products I need to establish if my category is not matched else product not found.

But my code product not found returned 20 times 🤨 see my output Screenshot

 html = `<p>Product not found</p>` // just + sign remove

I am trying another way it returns a single time but, if my condition is true the product does not show like

`if (post.category === "men's clothing")`

How can I solve it?

// Men catagory 
men.addEventListener('click', loadDataMen);
function loadDataMen() {

    fetch('./src/db/db.json')
        .then(function (response) {
            return response.json();
        })


        .then(function (info) {

            let html = '';

            info.filter((post) => {
                try {

                    if (post.category === "no match") {
                        html += `
                        
                        <div class="single_product product-box bg-darkopacity rounded-20 position-relative mb-5 grid_view p-3">
                                <!-- 
                                    Hover Zoom you can cancel if you don't like it just remove "hover-zoom" class  
                                -->
                                <div class="hover-zoom drop-shadow-product position-relative">
                                    <!-- PLaceholder Image  -->
                                    <img src="${post.image}" alt="Image" />
                                    <!-- User Rating  -->
                                    <div class="show-rating">
                                        <div class="rate">
                                            ${post.rating.rate} ⭐ | ${post.rating.count}
                                        </div>
                                    </div>
                                </div>
            
                                <!-- Product Wishlist  -->
                                <div class="love bubbly-button">
                                    <i class="fa-regular fa-heart"></i>
                                </div>
                                <!-- Product Offer  -->
                                <div class="product-tag-warning badge bg-warning">${post.tag}</div>
        
                                <div class="product-functionality text-center mt-3">
                                    <!-- Product title  -->
                                    <div class="product-title fw-bold text-break">
                                    ${post.title.substring(0, 18)}...
                                    </div>
                                    <!-- Product price  -->
                                    <div class="product-price mb-2"><strong>${post.price} only</strong></div>
                                    
                                    <!-- Router navigation  -->
                                    <div class="two-btn-sm">
                                        <a href="./src/pages/product/single-product.html" class="btn-1 shadow-box-2">View</a> 
                                        <a href="./src/pages/shop/shop_1.html" class="btn-2 shadow-box-2">Buy</a>
                                    </div>
                                </div>
                                <!-- Product Description  -->
                                <div class="discription">
                                    <small class="text-decoration-underline">
                                        <strong>Discription</strong>
                                    </small>
                                    <p class="p-0">
                                        ${post.description} <a href="#">SeeMore</a>
                                    </p>
                                </div>
                            </div>
                        `;
                    }

                    else{

                        html += `<p>Product not found</p>`

                    }

                } catch (error) {
                    html = `<p>Somthing went wrong ${error}</p>`
                }
            })

            output.innerHTML = html

        })
        .catch(function (error) {
            console.log(error)
        })
}

1 Answer 1

1

The problem is that you are using the filter method as a loop.

For more info about filter method check this out: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

You must filter your posts result using a condition like so:

let filteredPosts=info.filter((post)=>post.category === "no match");

then doing something like that:

if(filteredPosts.length<=0){
  html='Product not found'
}else{
  filteredPosts.splice(4); //only 4 posts
  for(let post of filteredPosts){
     html+=....
  }
}

Improved response:

What you have to do to filter by category or color or both, you must save which category and color the user has selected:

let selectedCategory=null;
let selectedColor=null;

let categoryItems=document.getElementByClassName('category'); //assuming categories items has a class category

for(let categoryItem of categoryItems){
   //foreach category found
   categoryItem.addEventListener('click', function(event){
       selectedCatory=this.innerHTML; //get the clicked category
       showFilteredItems();
   });
}

let colorsItems=document.getElementByClassName('color'); 
//assuming colors items has a class color

for(let colorItem of colorsItems){
   //foreach color found
   categoryItem.addEventListener('click', function(event){
       selectedColor=this.innerHTML; //get the clicked color
       showFilteredItems();
   });
}

//this function is your old method
function showFilteredItems(){
  ....
  fetch(...)
  ....

  //by default all results
  let filteredPosts=info;

  //category filter
  if(selectedCategory){
    filteredPosts=filteredPosts.filter((post)=>post.category === selectedCategory);
  }
  //color filter
  if(selectedColor){
    filteredPosts=filteredPosts.filter((post)=>post.color=== selectedColor);
  }

  //show the items
  if(filteredPosts.length<=0){
     html='Product not found'
  }else{
    filteredPosts.splice(4); //only 4 posts
    for(let post of filteredPosts){
      html+=....
    }
  }
}

Keep in mind that in production application, we prefer to send filters(category and color) to the backend of the application that way you will not receive all the items (this can be really slow if you have thousands of items) but only the filtered.

Sign up to request clarification or add additional context in comments.

9 Comments

How can I Control like I have 20 products I need only 4 Product?
by doing something like filteredPosts.splice(4) before the for loop. Check out the updated response.
Like I get category products or my category is match. But if I need under each category product like post.color === "red" how can I get data? Under my match category 🤔. I want to use DRY method.
I don't really understand what you want. Can you show us the data? and how the page should appears?
here is my code info plz open the image link{ "id": 15, "title": "p-title", "category": "women", "color": "red", "image": "../../images/product/v0/p15.jpg" } link
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.