1

So now i'm doing this to organise my results by category but if feel like this could be better:

<div><h2>Gloves</h2></div>
<div v-for="stash in stashes" :key="stash.id">
  <div v-for="item in stash.items" :key="item.id">
    <div v-if="item.extended.subcategories[0] === 'gloves'">
      {{ item.extended.baseType }}
    </div>
  </div>
</div>
<div><h2>Boots</h2></div>
<div v-for="stash in stashes" :key="stash.id2">
  <div v-for="item in stash.items" :key="item.id2">
    <div v-if="item.extended.subcategories[0] === 'belt'">
      {{ item.extended.baseType }}
    </div>
  </div>
</div>
<div><h2>Helmets</h2></div>
..
<div><h2>Weapons</h2></div>
..

If found this article doing this with a computed property and i feel like this should be the way but can't get it to work (also because i need a argument for it to work this way i think?):

  computed: {
    filter(category) {
      return this.stashes.items.filter(a => a.extended.subcategories[0] === category);
    }
  }

and then something like this:

<div v-for="item in filter('gloves')" :key="item.id">
 ..
</div>

But yeah, it says i can't pass a argument in that for loop like this so that is where i ended for now.

Anyone got an idea how to do this?

Stashes looks like this:

stashes: [
  {
    id: 1
    items: [{
      name: 'lorem',
      extended: {
        subcategories: ["gloves"]
      }
    }]
  },
  {
    id: 2
    items: [{
      name: 'ipsum',
      extended: {
        subcategories: ["boots"]
      }
    }]
  },
]
Awesom-o
  • 105
  • 1
  • 12

2 Answers2

2

While using a method in the template might solve this, it's not a good pattern because it causes the method to run every time the template is rerendered for any reason. Add another level of v-for:

<div v-for="category in categories" :key="category">
  <div><h2>{{ category }}</h2></div>
  <div v-for="stash in stashes" :key="stash.id">
    <div v-for="item in stash.items" :key="item.id">
      <div v-if="item.extended.subcategories[0] === category">
        {{ item.extended.baseType }}
      </div>
    </div>
  </div>
</div>

And create an array of categories like:

data() {
   return {
      categories: ['gloves','belt']
   }
}
Dan
  • 45,062
  • 13
  • 59
  • 80
  • This makes so much sense Thank you Dan! Must say that it's sometimes a little bit frustrating struggling with something only to find out the solution is this simple. – Awesom-o Apr 23 '20 at 08:52
  • You're welcome. It's ok, you may become more familiar with patterns once you see and use them – Dan Apr 23 '20 at 08:54
  • Here's an idea for a data structure that wouldn't force you to loop through every single item on every single category. As it is now, it could become slow if there were lots of categories with lots of items. This way only loops over items that are known to be in the current category iteration: https://jsfiddle.net/sh0ber/93xrmq2h/ Check the `stashes` structure – Dan Apr 23 '20 at 10:11
  • Awesome Dan! The stashes data now comes from an API. Would restructuring it before i work with it be something i should consider? It's quite a bit of data. – Awesom-o Apr 23 '20 at 10:59
  • If it would only need to be done once (because the original data doesn't change), I would say yes. But maybe you can wait and see if performance becomes an issue, since that's the only reason to do it. In that case, it would be worth it to restructure once to save lots of extra looping in the template. – Dan Apr 23 '20 at 11:11
0

You can achieve this by returning a method from your computed but I do not recommend this solution. Instead of computed I recommend you to use a method.

[RECOMENDED]

method: {
    filter(category) {
      return this.stashes.items.filter(a => a.extended.subcategories[0] === category);
    }
  }

[USING COMPUTED]

computed: {
    filter() {
      return category => this.stashes.items.filter(a => a.extended.subcategories[0] === category);
    }
  }

Here you can read a little more about this: Why I can not pass parameter to the computed

Krzysztof Kaczyński
  • 1,671
  • 1
  • 10
  • 26
  • Thanks Krzysztof, although Dan's aprouch seems the way to go..i'll read up on the thread you linked! – Awesom-o Apr 23 '20 at 08:53