Alauddin Ahmed
Alauddin Ahmed

Reputation: 151

global event not firing to other component after destroying from one vuejs 2

I'm new in vuejs 2. I have many component and I'm having problem in global event handling, here is my component structure -> Image . I'm using Dynamic-Component to handle my components. I have forms in component 1 and 2. If i submit the form, it will be saved in allData.js file, and will show there. So as i study and found that, to communicate with components i need to use global event handler(eventBus). Here is my code (only scripted part included):

in my main.js, i included this:

import Vue from 'vue';
import App from './App.vue';
import allData from './components/allDataTemplate.vue';

Vue.prototype.$eventHub = new Vue();
//Other codes

by that $eventHub will be accessible from any component and i don't have to import to any other component.

In my App.js, i included all my form components:

  import componentOne from './components/componentOneTemplate';
  import componentTwo from './components/componentTwoTemplate';
  //Other codes

Im my componentOne/Two I'm emmiting event like this:

this.$eventHub.$emit('DataPassed', formData);

Now in allData.js, file where i need to listen to this handler (probably the problematic part), i'm listening to that event, and destroying it when leaving it:

methods: {
    whenCalled() {
        console.log('fired');
    }
},
created() {
    this.$eventHub.$on('DataPassed', this.whenCalled);
},
beforeDestroy() {
    this.$eventHub.$off('DataPassed', this.whenCalled);
}

Problem No 1: Here event not listening if i destroyed the event. Problem No 2: But if i comment out destroy event i can listen the event, which bring another problem. It triggering many times(the count of time that i visit the tab). Can anyone help me how to solve this problem?

Upvotes: 1

Views: 1220

Answers (2)

csantana
csantana

Reputation: 576

I think you should do

this.$eventHub.$on('DataPassed', this.whenCalled.bind(this));

or you can do

this.$eventHub.$on('DataPassed', () => { this.whenCalled });

I suspect this issue is related to the scope of the function 'whenCalled' in how you declare it in $on

Please check this link, i did a helper class which is injected as a VueHelper, the advantage is you can throw events inside the components and js files (no components) as well. I'm using this code and i am sure it works. https://kopy.io/ncytP

Updated kopy.io https://kopy.io/5u63D

Update: Since the kopy files has an expiration i will add the full code below

// Class EventEmitter
// events/index.js
import Vue from 'vue'

export class AppEventEmitter {
  constructor () {
    this.evt = new Vue()
  }

  listen (evt, callback) {
    this.evt.$on(evt, callback)
  }

  fire (evt, data = null) {
    this.evt.$emit(evt, data)
  }

  destroy (evt, callback) {
    this.evt.$off(evt, callback)
  }
}

export const AppEvent = new AppEventEmitter()
________________________________________________
// Main.js
import { AppEvent } from 'src/events'
Vue.prototype.$event = AppEvent

// Usage in vue components
    this.$event.listen('ChartDataPassed', () => { this.whenCalled() }) 
    this.$event.fire('ChartDataPassed', { value: 1, key: 'value' })
    this.$event.destroy('ChartDataPassed', () => { this.whenCalled() });

 // Usage in JS files
 // It works even if you also throw the event in other js files by doing
    AppEvent.fire('submission-process:photos-completed', { value: 1, key: 'value' })

Upvotes: 2

Ashraful
Ashraful

Reputation: 1964

You must write like following...

this.$eventHub.$on('DataPassed', function(payload) {
    // Here you can do anything with your passed data as payload
});

ES6 Format,

this.$eventHub.$on('DataPassed', (payload) => {
    // try something from here.
})

Upvotes: 1

Related Questions