Joney Spark
Joney Spark

Reputation: 265

How to find array item inside another array item in vue?

I'm trying to make a wishlist where I use localstorage. When clicked on "add to wishlist" button the item is added to localstorage and then shows "remove from wishlist" button. I was trying to computed using filter and find ES6 but I might got it wrong. Here is my codesandbox-link and also below is the code. Please someone help thanks.

https://codesandbox.io/s/wishlist-ouuyw?file=/src/App.vue

<template>
  <div id="app">
  <h2>Total Selected: {{selectedEntries.length}}</h2>
    <div v-for="entry in entries" :key="entry.id">
      <div class="content-wrap">
      
        <h3>{{entry.title}}</h3>
        <button v-if="!checkExists" @click="addToWishlist(entry.id)">Add Wishlist</button>
        <button v-else @click="removeToWishlist(entry.id)">Remove Wishlist</button>
      </div>
    </div>
  </div>
</template>

<script>

export default {
  name: "App",
  data(){
    return{
      entries: [
        {
          title: 'entry one',
          id: 1
        },
        {
          title: 'entry two',
          id: 2
        },
        {
          title: 'entry three',
          id: 3
        },
        {
          title: 'entry four',
          id: 4
        },
        {
          title: 'entry five',
          id: 5
        },
      ],
      selectedEntries: JSON.parse(window.localStorage.getItem("wishlistItems")) || []
    }
  },
  computed:{
    checkExists(){
      return this.entries.filter(entryItem => {
         this.selectedEntries.find(selectedId => {
           return entryItem.id === selectedId.id
         })
      })
    }
  },
  methods:{
    addToWishlist(entryId){
      this.selectedEntries.push({ id: entryId });
      window.localStorage.setItem("wishlistItems", JSON.stringify(this.selectedEntries));
      console.log("Clicked>>>", this.selectedEntries)
    }
  }
};
</script>

<style scoped>
.content-wrap{
  display: flex;
  border: 1px solid;
  margin: 5px;
  padding: 5px;
  align-items: center;
}
.content-wrap h3{
  text-transform: capitalize;
  width: 30%;
}
.content-wrap button{
  border: none;
  padding: 10px 20px;
  height: 30px;
  background-color: #1d9a61;
  color: #fff;
  font-size: 16px;
  cursor: pointer;
  line-height: .7
}
</style>



Upvotes: 1

Views: 560

Answers (1)

Salvino D&#39;sa
Salvino D&#39;sa

Reputation: 4506

You can create a method which checks if the object is present in the selected objects array and shows the respective buttons accordingly. I'm not sure why you only wish to keep it as a computed property. Because computed properties are not really used for computing values of array elements on the fly. Computed property methods don't take in an argument, so its not directly possible. Computed properties are used more for single values defined in the data property. Look at their official documentation.

So if you want to go with a computed property only, then you will have to create a computed property for fetching the matching items and then create another method that basically takes in this matching items array and the current entry.id and returns a boolean. But this is not a good solution. Ideal solution would be to just have it as a method that takes the current entry.id as an argument as shown below.

.

<template>
  <div id="app">
  <h2>Total Selected: {{selectedEntries.length}}</h2>
    <div v-for="entry in entries" :key="entry.id">
      <div class="content-wrap">
      
        <h3>{{entry.title}}</h3>
        <button v-if="!checkExists(entry.id)" @click="addToWishlist(entry.id)">Add Wishlist</button>
        <button v-else @click="removeToWishlist(entry.id)">Remove Wishlist</button>
      </div>
    </div>
  </div>
</template>

<script>

export default {
  name: "App",
  data(){
    return{
      entries: [
        {
          title: 'entry one',
          id: 1
        },
        {
          title: 'entry two',
          id: 2
        },
        {
          title: 'entry three',
          id: 3
        },
        {
          title: 'entry four',
          id: 4
        },
        {
          title: 'entry five',
          id: 5
        },
      ],
      // selectedEntries: JSON.parse(window.localStorage.getItem("wishlistItems")) || [],
      selectedEntries: [{
          title: 'entry one',
          id: 1
        },
        {
          title: 'entry two',
          id: 2
        }],
    }
  },
  methods:{
    addToWishlist(entryId){
      this.selectedEntries.push({ id: entryId });
      window.localStorage.setItem("wishlistItems", JSON.stringify(this.selectedEntries));
      console.log("Clicked>>>", this.selectedEntries)
    },

    checkExists(entryId){
      return this.selectedEntries.find(item => item.id === entryId);
    }
  }
};
</script>

<style scoped>
.content-wrap{
  display: flex;
  border: 1px solid;
  margin: 5px;
  padding: 5px;
  align-items: center;
}
.content-wrap h3{
  text-transform: capitalize;
  width: 30%;
}
.content-wrap button{
  border: none;
  padding: 10px 20px;
  height: 30px;
  background-color: #1d9a61;
  color: #fff;
  font-size: 16px;
  cursor: pointer;
  line-height: .7
}
</style>

Upvotes: 2

Related Questions