ST80
ST80

Reputation: 3903

VueJS How to pass data to a modal component using eventbus

I'm building a small vue application where among other things it is possible to delete an entry of a music collection. So at this point I have a list of music albums and next to the entry I have a "delete" button. When I do the following:

<li v-for="cd in cds">
   <span>{{cd.artist}} - {{cd.album}}</span> <button v-on:click="deleteAlbum(cd.ID)">Delete</button>
</li>

and then in my methods do:

deleteAlbum(id){   
 this.$http.delete('/api/cds/delete/'+id)
    .then(function(response){
        this.fetchAll()
    // });
},

this works fine so far, but to make it more nice, I want the delete functionality to appear in a modal/popup, so I made the following changes:

<li v-for="cd in cds">
   <div class="cd-wrap">
     <span>{{cd.artist}} - {{cd.album}}</span>
     <button @click="showDeleteModal({id: cd.ID, artist: cd.artist, album: cd.album})" class="btn">Delete</button>
   </div>
  <delete-modal v-if="showDelete" @close="showDelete = false" @showDeleteModal="cd.ID = $event"></delete-modal>
</li>

so, as seen above I created a <delete-modal>-component. When I click on the delete button I want to pass the data from the entry to <delete-modal> component with the help of an eventbus. For that, inside my methods I did this:

showDeleteModal(item) {
  this.showDelete = true
  eventBus.$emit('showDeleteModal', {item: item})
}

Then, in the <delete-modal>, inside the created()-lifecycle I did this:

created(){
  eventBus.$on('showDeleteModal', (item) => {
    console.log('bus data: ', item)
  })  
}

this gives me plenty of empty opened popups/modals!!??

Can someone tell me what I'm doing wrong here?

** EDIT **

After a good suggestion I dumped the eventBus method and pass the data as props to the <delete-modal> so now it looks like this:

<delete-modal :id="cd.ID" :artist="cd.artist" :album="cd.album"></delete-modal>

and the delete-modal component:

export default {
   props: ['id', 'artist', 'album'],
   data() {
     return {
        isOpen: false
     }
   },
   created(){
     this.isOpen = true
   }

}

Only issue I have now, is that it tries to open a modal for each entry, how can I detect the correct ID/entry?

Upvotes: 2

Views: 11172

Answers (1)

Roland
Roland

Reputation: 27819

I am going to show you how to do it with props since it is a parent-child relation.I will show you a simple way of doing it.You need to modify or add some code of course in order to work in your app.

Parent component

<template>
    <div>
       <li v-for="cd in cds" :key="cd.ID">
         <div class="cd-wrap">
           <span>{{cd.artist}} - {{cd.album}}</span>
           <button 
              @click="showDeleteModal({id: cd.ID, artist: cd.artist, album: cd.album})" 
              class="btn"
           >
            Delete
           </button>
         </div>

         <delete-modal v-if="showDelete" :modal.sync="showDelte" :passedObject="objectToPass"></delete-modal>
       </li>
    </div>
</template>
<script>
import Child from 'Child'
    export default {
        components: {
            'delete-modal': Child
        },
        data() {
            return {
                showDelete: false,
                objectToPass: null,
                //here put your other properties
            }
        },
        methods: {
            showDeleteModal(item) {
              this.showDelete = true
              this.objectToPass = item
            }
        }
    }
</script>

Child Component

<template>
    /* Here put your logic component */
</template>
<script>
    export default {
        props: {
            modal:{
                default:false
            },
            passedObject: {
                type: Object
            }
        },
        methods: {
            closeModal() { //the method to close the modal
                this.$emit('update:modal')
            }
        }
        //here put your other vue.js code

    }
</script>

When you use the .sync modifier to pass a prop in child component then,there (in child cmp) you have to emit an event like:

this.$emit('update:modal')

And with that the modal will close and open.Also using props we have passed to child component the object that contains the id and other stuff.

If you want to learn more about props, click here

Upvotes: 6

Related Questions