0

Initially I have a list of animations stored in Cards. Each card has a few tags. From a top filter menu I want to be able to display only Cards, that match with the filter that has been set. A vuex state holds the information of all currently applied filters.

My markup looks like this:

    <div class="Feed__cards">
      <Card
        v-for="(card, index) in filteredCards"
        :key="card.id"
        :id="card.id"
        :name="card.name"
        :tags="card.tags"
        :description="card.description"
        :video="card.video"
        :valueset="getValueSet(index)"
        class="Feed__card"
      >
      </Card>

In my methods I wanted to do something like this (activeTagsElements is a computed property, mapState from Vuex):

compare(tags) {
      tags.forEach(tag => {
        if(this.activeTagsElements.includes(tag)){
          return true
        }
      })
    },
 getAllAnimations() {
      this.$axios.get('/api/animations/all')
       .then(response => {
        this.allCards = response.data;
        this.allMaxIndex = response.data.length - 1;
        response.data.forEach((animation, index) => {
          this.getTags(animation.id, index, this.allCards, this.allMaxIndex, 'all');
        });
      }).catch((error) => {
        console.log(error)
      })
    },
getTags(id, index, slot, max, type) {
      this.$axios.get('/api/animationtags/' + id)
       .then(response => {
         slot[index].tags = response.data.map(tag => {
          return tag.name;
        });
        if(index == max && type == 'initial'){
          this.initialLoad = true;

        } else if(index == max && type == 'all') {
          this.allLoad = true;
        }
      }).catch((error) => {
        console.log(error);
      })
    }

I also tried watching the change of the vuex state but couldn't get to the point of how to get the actual tags from each element to compare it to the vuex state.

Any hints are very appreciated.

1 Answer 1

1

The vue way is to create a computed property of the filtered tasks. Then you just v-for throught them.

<Card
 v-for="card in filteredAnimations"
 :key="card.id"
 :id="card.id"
 :name="card.name"
 :tags="card.tags"
>
</Card>

This should work, and is efficient as it will only rerun filteredTags if either Vuex store changes or the activeElements from your filter changes.

<script>
export default {
    data() {
        return {
            activeTagsElements: []
        }
    },
    computed: {
        animations() {
            return this.$store.animations
        },
        filteredAnimations() {
            return this.animations.filter(animation => {
                return this.activeTagsElements.includes(animation)
            })
        }
    }
}
</script>
Sign up to request clarification or add additional context in comments.

5 Comments

I think this answer is still missing the option to check for different tags as a component has more than one tags applied, that's why I had the forEach initially. How can this be included? I think the filteredTags() should iterate over card instead of tags and the second loop needs to be card.tag in order to get it right?
I'm not really getting the big picture. You have an array of cards, each card has an array of tags and an array of animations. You want to filter the cards by the tags it has. Correct?
Basically yes, animations and cards are the same and every card/animation has an array of tags
I think I get it, but edit your post and show the full component please
I added in more of the relevant parts of the component, otherwise it would be more confusing. Via the API I get animations and tags. As already mentioned the tags are stored in an Array inside of the allCards object

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.