2

I am building a site where users can upload posts. Every user has a profile page where they can see what posts they have liked and what posts they have created. Over a created post there is a delete button. When I delete the post, it gets removed, but only from the back end. On the home page and profile page (if I go to the profile page again) the post is still there. If I refresh the page everything is working perfectly, but there must be a way to make that happen without refreshing right?

I am having trouble re-rendering the components. I am very new to programming as you can see. With this delete method I need to update 3 components (Home.vue, Posts.vue and Profile.vue).

My profile component/page's delete button html:

<v-container class="mt-3" v-else>
  <v-flex xs12>
    <h2 class="font-weight-light">
      Created posts
      <span class="font-weight-regular">({{ userPosts.length }})</span>
    </h2>
  </v-flex>
  <v-layout row wrap>
    <v-flex xs12 sm6 v-for="post in userPosts" :key="post._id">
      <v-card class="mt-3 ml-1 mr-2" hover>
        <v-btn color="info" floating fab small dark @click="loadPost(post)">
          <v-icon>edit</v-icon>
        </v-btn>
        <v-btn
          color="error"
          floating
          fab
          small
          dark
          @click="handleDeleteUserPost(post)"
        >
          <v-icon>delete</v-icon>
        </v-btn>

        <v-img
          height="30vh"
          :src="post.imageUrl"
          @click="goToPost(post._id)"
        ></v-img>
        <v-card-text>{{ post.title }}</v-card-text>
      </v-card>
    </v-flex>
  </v-layout>
</v-container>

the lifecycle hooks below. it is under "methods" :

    handleDeleteUserPost(post) {
  this.loadPost(post, false);
  const deletePost = window.confirm("Do you want to delete your post?");
  if (deletePost) {
    this.$store.dispatch("deleteUserPost", {
      postId: this.postId,
    });
  }
}

the vuex store component's delete functionality. it is under "action":

 deleteUserPost: ({ state, commit }, payload) => {
  apolloClient
    .mutate({
      mutation: DELETE_USER_POST,
      variables: payload,
    })
    .then(({ data }) => {
      const index = state.userPosts.findIndex(
        (post) => post._id === data.deleteUserPost._id
      );
      const userPosts = [
        ...state.userPosts.slice(0, index),
        ...state.userPosts.slice(index + 1),
      ];
      commit("setUserPosts", userPosts);
    })
    .catch((err) => {
      console.error(err);
    });
}

mutations from "store"

 mutations: {
setPosts: (state, payload) => {
  state.posts = payload;
},
setSearchResults: (state, payload) => {
  if (payload !== null) {
    state.searchResults = payload;
  }
},
setUser: (state, payload) => {
  state.user = payload;
},
setUserPosts: (state, payload) => {
  state.userPosts = payload;
},
setLoading: (state, payload) => {
  state.loading = payload;
},
setError: (state, payload) => {
  state.error = payload;
},
setAuthError: (state, payload) => {
  state.authError = payload;
},
clearUser: (state) => (state.user = null),
clearError: (state) => (state.error = null),
clearSearchResults: (state) => (state.searchResults = []),

},

1 Answers1

2

Not sure if this will be enough to fix, but try replacing all this:

const userPosts = [
  ...state.userPosts.slice(0, index),
  ...state.userPosts.slice(index + 1),
];
commit("setUserPosts", userPosts);

with

commit("removeUserPost", index)

And create that mutation:

removeUserPost(state, index) {
  state.userPosts.splice(index, 1);  // <-- `splice` not `slice` here
}

If this isn't enough, make sure you are using userPosts in the component like:

computed: {
  userPosts() {
    return this.$store.state.userPosts;
  }
}
Dan
  • 59,490
  • 13
  • 101
  • 110
  • 1
    My apologies. I have edited in my mutations and I will try out your method. Thank you so much for answering. – Steve Jefferson Apr 08 '20 at 10:24
  • 2
    No worries, you're welcome. Make sure to refresh the page / this answer first, it may have been edited since you saw it last. – Dan Apr 08 '20 at 10:25
  • When I delete the post I get this error in the console "[Violation] 'click' handler took 1601ms". The post gets removed, but just like before if I go to a page that displays it or I return to the profile's component - it's still there. If I click on the deleted post I get this error: vue-apollo.esm.js?522d:637 GraphQL execution errors for query 'getPost' {name: "GraphQLError", message: "Cannot return null for non-nullable field Query.getPost."}. Any Ideas or is the situation FUBAR? – Steve Jefferson Apr 08 '20 at 10:32
  • 1
    Possibly due to `window.confirm`. It's unclear what `loadPost` is doing in a delete handler, we can't see what it does. We also can't see how you use `userPosts` in the component. Try the computed I mentioned if not already using one. Hard to say if FUBAR, but the app seems more complex than it needs to be. You could try posting the whole thing to https://www.codesandbox.io and linking it here – Dan Apr 08 '20 at 10:56
  • https://codesandbox.io/s/github/DimitarBelchev/Vue-Project-Softuni Thank you for helping. If there is anything I can do to help you understand the app,just ask! – Steve Jefferson Apr 08 '20 at 11:17