1

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>



1 Answer 1

2

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>

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

2 Comments

I'm very thankful to you. That's great. I understand fully and your explanation is awesome. Thanks a lot
@JoneySpark appreciate the kind words.. Thanks!

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.