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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.