'Delete an element from array nuxtjs

I am trying to delete an element from array but if i make 3 posts and i try deleting them the last one that remains is usually one that has already been deleted. Until I refresh.

<tr class="border-b" v-for="(post, i) in posts.data" :key="i">
  <td class="border-t-0 px-6 align-middle border-l-0 border-r-0 text-base whitespace-nowrap p-4 text-left flex items-center">
    {{ post.title}}
  </td>
  <td class="border-t-0 px-6 align-middle border-l-0 border-r-0 text-base whitespace-nowrap p-4">{{ post.excerpt}}</td>
  <td class="border-t-0 px-6 align-middle border-l-0 border-r-0 text-base whitespace-nowrap p-4">{{ post.updated_at }}</td>
  <td class="border-t-0 px-6 align-middle border-l-0 border-r-0 text-base whitespace-nowrap p-4"><NuxtLink :to="'/posts/edit/'+ post.id">Edit</NuxtLink></td>
  <td class="border-t-0 px-6 align-middle border-l-0 border-r-0 text-base whitespace-nowrap p-4 delete"
  @click="deletePost(post.id)"
  >
  <i class="fa fa-trash mr-2 text-sm" aria-hidden="true"></i>
  </td>
</tr>
export default {
  name: 'IndexPage',
  middleware: 'auth',
  components:{
    LeftBar,
    TopBar,
    Footer 
  },
  data: () => ({
    posts: []
  }),
  async fetch(){
    const response = await this.$axios.get('/api/posts')
    this.posts = response.data
  },
  methods: {
    deletePost(id){
      this.$axios.delete('/api/post/delete/' + id)
      .then(() => {
        if(id){
          this.posts.data.splice(this.posts.data.indexOf(id), 1)
        }
      })
    }
  },
  head(){
    return{
      title: 'All Posts'
    }
  },
}

How do i ensure that each element i click is the one deleted?



Solution 1:[1]

Observations :

  • As deletePost() method is responsible to make an API call to delete the selected record from the backend. Then, Why you are deleting that again at client side ? API should response with the filtered data and you can directly assign that in this.posts.
  • this.posts.data is an array of objects and id is a number. Hence, this.posts.data.indexOf(id) will not work.

Let me explain with a demo :

const app = new Vue({
  el: '#app',
  data() {
    return {
      posts: [{
        id: 1,
        title: 'Title 1',
        excerpt: 'Excerpt 1',
        updated_at: 'Updated 1'
      }, {
        id: 2,
        title: 'Title 2',
        excerpt: 'Excerpt 2',
        updated_at: 'Updated 2'
      }, {
        id: 3,
        title: 'Title 3',
        excerpt: 'Excerpt 3',
        updated_at: 'Updated 3'
      }, {
        id: 4,
        title: 'Title 4',
        excerpt: 'Excerpt 4',
        updated_at: 'Updated 4'
      }]
    }
  },
  methods: {
    deletePost(id) {
      // make an API call and bind the response directly in this.posts
      this.posts.forEach((obj) => {
        if (id === obj.id) {
          this.posts.splice(this.posts.indexOf(obj), 1);
        }
      })
    }
  }
})
.link {
  color: blue;
  cursor: pointer;
  text-decoration: underline;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.0/vue.js"></script>
<div id="app">
  <table>
    <tr v-for="post in posts" :key="post.id">
      <td>{{ post.title}}</td>
      <td>{{ post.excerpt}}</td>
      <td>{{ post.updated_at }}</td>
      <td class="link" @click="deletePost(post.id)">Delete</td>
    </tr>
  </table>
</div>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Rohìt Jíndal