Search code examples
javascriptvuejs2

Vue js 2 how to return filtered array from Parent to Child component by replacing the current array prop


I am using Vuejs 2. I have a child component from which I am emiting an event,

Child code

this.$emit("remove-blocked-user-posts", blockedUserName);

In parent, I have post array prop which I am passing to the child. I am receiving the event in parent,

parent code

 props: {
        posts: Array,
        .....
    }

.......

 methods: {
      removeBlockedUserPosts(blockedUserName){

        const postData = this.posts.filter(
            (post) => post.userName !== blockedUserName
        );
      
        //Here is how to set the filtered postData to the Post array prop ?
       // how to set this filtered value to the Post prop array with
      // this.$set(someobject, 'key', 'value')
        
    }

I need to set the filtered post by replacing the current Post array prop to pass to the child component. But I can't do it with this.$set. I need to pass only the filtered array from the parent.


Solution

  • You can't (should not) reassign new values to a prop. If you encounter this situation, you need to re-emit the value from the parent to its grand-parent component until you reach the component where you've defined posts.

    Depending on your needs. I'd do the filtering by a some reactive state.

    So in your parent components removeBlockedUserPosts method, you can emit another event:

    removeBlockedUserPosts(blockedUserName){
      this.$emit('block-username', blockedUserName)
    }
    

    You should then have somewhere defined posts in a grand-parent:

    <template>
      <Parent :posts="filterdPosts" @block-username="onBlockUsername" />
    </template>
    
    <script>
    export default {
      name: 'GrandParent',
      data() {
        return {
          posts: [],
          blockedUsername: null,
        }
      },
      computed: {
        filteredPosts() {
          return this.blockedUsername ? this.posts.filter(p => p.userName !== this.blockedUserName) : this.posts
        }
      },
      mounted() {
        fetchPosts()
      },
      methods: {
        fetchPosts() {...},
        onBlockUsername(username) {
          this.blockedUserName = username
        }
      }
    }
    </script>