Vue $emit not works properly on dynamic component /promise

880 Views Asked by At

I have created a table component which accept dynamic data (th, tr, td,...). Table data (td) could be a dynamic component as below:

<td>
  <component
    :is="data.content"
    :colspan="data.colspan"
    v-bind="data.props"
    v-on="data.events"/>
</td>
...
export default {
 name: "DynamicTable",
 props: {
  ...
  isLoading : { // loading slot will be used if true
  type: Boolean,
  default: false
  }
 }
}

I feed required data in another component like this:

<other-html-elements/>
<dynamic-table
  :table-heads="tableHeads"
  :table-rows="tableRows"
  :is-loading="isLoading">
...
computed: { ...
tableRows () {...
 new TableData(CancelOrderButton, 'component', {
     props: {
       order
     },
     events: {
       'updateLoadingStatus': this.updateLoadingStatus
     }
   })
...
methods: { ...
updateLoadingStatus (status) {
  this.isLoading = status
}

and here is my CancelOrderButton:

methods: {
 cancelOrder () {
  this.$emit('updateLoadingStatus', true)
  somePromise().finally(() => {
    this.$emit('updateLoadingStatus', false)
    })

once I click on a button and invoke the cancelOrder method, the updateLoadingStatus will be emitted without any problem. and after the promise settled, it will be emitted again. but the handler will not triggered. I have checked everything. I'm sure that events are emitted. this problem will be fixed when I move the second emit statement out of the finally block or I if do not pass isLoading as a props for the dynamicTable.

1

There are 1 best solutions below

2
On

Try setting the prop for that emit like this:

<dynamic-table
  :table-heads="tableHeads"
  :table-rows="tableRows"
  @update-loading-status="updateLoadingStatus"
  :is-loading="isLoading">

And calling that emit like this (although it should work as you have it):

this.$emit('update-loading-status', true)

Also you can define them in a general way and use them in the component you want: https://v2.vuejs.org/v2/guide/custom-directive.html