0

I would like to filter an array of objects based on the objects attributes. Let me show you what I mean with the code. First of all I have an array where I store the information of the objects:

var data = [
  {
    product: "Haori Jacket",
    url: "haorijacket.html",
    image: "img/haori-jacket.jpg",
    altDesc: "Jacket",
    price: "$210.00",
    outwear: ""
  },
  {
    product: "Swing Dress",
    url: "swingdress.html",
    image: "img/swing-dress.jpg",
    altDesc: "Dress",
    price: "$218.00",
    dress: ""
  },
  {
    product: "Tan Tote",
    url: "",
    image: "img/tan-tote.jpeg",
    altDesc: "Backpack",
    price: "$350.00",
    sale: "$475.00",
    accessory: ""
  },
  {
    product: "Sunglasses Nº 1",
    url: "",
    image: "img/sunglasses-n1.jpeg",
    altDesc: "Sunglasses",
    price: "$125.00",
    accessory: ""
  },
  {
    product: "Sunglasses Nº 2",
    url: "",
    image: "img/sunglasses-n2.jpeg",
    altDesc: "Sunglasses",
    price: "$125.00",
    accessory: ""
  }
];

Then dynamically generate a string using a Template Literal with a function:

 // Template literal
    function clothingView(item, index) {
      return (`
        <a href="${item.url}" class="shop-item">
        ${item.sale ? `<span class="shop-item__sale">Sale</span>`: ''}
          <img data-src=${item.image} alt="${item.altDesc}" class="shop-item__img">
          <div class="quickview">
            <span class="quickview__icon">Quick View</span>
            <span class="quickview__info">${item.product}
              <br>
              <span class="quickview__price">${item.price}
                ${item.sale ? `<span class="quickview__price--sale">${item.sale}</span>`: ''}
              </span>
            </span>
            <span class="shop-item__index">${index}</span>
          </div>
        </a>
        `);
    };

// Append template literal to html structure
for (var i = 0; i < data.length; ++i) {
  $('.all-items').append(clothingView(data[i], i))
}

I have a div with the class "all-items" which contain all my objects (38 to be exact) but I also want to divide these objects in categories (accesories, dresses, outwear, etc..). I am trying to do this using the filter method. Here's some images to help clarify the situation: all items accesories section

Basically I'd like to append to my div with the class "accesories" only the objects with the attribute "accesory". How can I do this? Any help is much appreciated!

edit: let me also include the html structure just in case:

<section class="products-container container">
      <nav class="categories">
        <span class="categories__link" id="accesories">Accesories</span>
        <span class="categories__link" id="bottoms">Bottoms</span>
        <span class="categories__link" id="dresses">Dresses + Jumpsuits</span>
        <span class="categories__link" id="outwear">Outerwear</span>
        <span class="categories__link" id="tops">Tops</span>
        <span class="categories__link" id="sale">— Sale</span>
      </nav>
      <div class="products all-items">
        <!-- <a href="haorijacket.html" class="shop-item">
          <span class="shop-item__sale">Sale</span>
          <img src=img/haori-jacket.jpg alt="Jacket" class="shop-item__img">
          <div class="quickview">
            <span class="quickview__icon">Quick View</span>
            <span class="quickview__info">$Haori Jacket
              <br>
              <span class="quickview__price">$210.00<span class="quickview__price--sale">$150.00<span></span>
            </span>
            <span class="clothing-index">${index}</span>
          </div>
        </a> -->
      </div>
      <div class="products accesories"></div>
      <div class="products bottoms"></div>
      <div class="products dresses"></div>
      <div class="products outwear"></div>
      <div class="products tops"></div>
      <div class="products sale"></div>
    </section>
1
  • Hey @Ele, can you elaborate your answer, I don't quite understand what you mean by that. Commented Jul 17, 2018 at 23:03

2 Answers 2

1

You can use the in operator to check if a specific property exists within an object.

The in operator returns true if the specified property is in the specified object or its prototype chain.

var allItems = $('div.all-items');
var accesoryItems = $('div.accesories');
for (var i = 0; i < data.length; ++i) {
    var clothingView = clothingView(data[i], i);
    if ('accessory' in data[i]) accesoryItems.append(clothingView);
    else allItems.append(clothingView);
}

Of course, you need to add the necessary if-else-if to add the views to specific divs.

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

4 Comments

for (var i = 0; i < data.length; ++i) { const viewItems = clothingView(data[i], i); if ('accessory' in data[i]) { $('.accesories').append(viewItems); } if ('bottom' in data[i]) { $('.bottoms').append(viewItems) } if ('dress' in data[i]) { $('.dresses').append(viewItems); } if ('outwear' in data[i]) { $('.outwear').append(viewItems); } if ('top' in data[i]) { $('.tops').append(viewItems); } if ('sale' in data[i]) { $('.sale').append(viewItems); } else { $('.all-items').append(viewItems); } };
with the code above some of the items are missing in the "all-items" container for some reason and I don't know why. I want all the items to be in that container too.
Just to clarify that I solved it like this for (var i = 0; i < data.length; ++i) { const viewItems = clothingView(data[i], i); $('.all-items').append(viewItems); if ('accessory' in data[i]) { $('.accesories').append(viewItems); } if ('bottom' in data[i]) { $('.bottoms').append(viewItems); } if ('dress' in data[i]) { $('.dresses').append(viewItems); } if ('outwear' in data[i]) { $('.outwear').append(viewItems); } if ('top' in data[i]) { $('.tops').append(viewItems); } if ('sale' in data[i]) { $('.sale').append(viewItems); } };
There was nothing wrong with your code of course, it was just a conflict with the else if statement since one object could be in different sections due to its attributes.
0

You can try this:

function filterItems(itemType) {
    return data.filter(function(i) {return i[itemType] !== undefined});
}

This should be okay for IE9+ and modern browsers.

Comments

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.