0

I am trying to do communication between two components using $emit and $on:

I am unable to communicated between the two components and unable to update highcharts-chart in component-B from click event in component-A.

JavaScript Code for Component-A:

import Vue from 'vue';

const bus = new Vue();

const pause = ms => new Promise(resolve => setTimeout(resolve, ms));


export default {

  data: () => ({
    active: [],
    avatar: null,
    open: [],
    users: [],
  }),

  computed: {
    items() {
      return [
        {
          name: 'Users',
          children: this.users,
        },
      ];
    },
    selected() {
      if (!this.active.length) return undefined;

      const id = this.active[0];

      return this.users.find(user => user.id === id);
    },
  },

  methods: {

    fetchData() {
      const id = this.active[0];
      this.parts = this.users.find(user => user.id === id);
      bus.$emit('new_parts', this.parts.data);
      console.log(this.parts.data);
    },


    async fetchUsers(item) {
      // Remove in 6 months and say
      // you've made optimizations! :)
      await pause(1500);

      return fetch('http://localhost:8081/api/toppartsdata')
        .then(res => res.json())
        .then(json => (item.children.push(...json)))
        .catch(err => console.warn(err));
    },

  },
};

JavaScript Code for Component-B:

    import VueHighcharts from 'vue2-highcharts';
import Vue from 'vue';

const bus = new Vue();

const asyncData = {
  name: 'Prediction Chart',
  marker: {
    symbol: 'circle',
  },
  data: [],
};
export default {
  components: {
    VueHighcharts,
  },
  data() {
    return {
      options: {
        chart: {
          type: 'spline',
          title: '',
        },
        xAxis: {
          categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
            'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
        },
        yAxis: {
          title: {
            text: 'LINECOST',
          },
          labels: {
            formatter() {
              return `${this.value}°`;
            },
          },
        },
        tooltip: {
          crosshairs: true,
          shared: true,
        },
        credits: {
          enabled: false,
        },
        plotOptions: {
          spline: {
            marker: {
              radius: 4,
              lineColor: '#666666',
              lineWidth: 1,
            },
          },
        },
        series: [],
      },
    };
  },
  methods: {
    test() {
      // eslint-disable-next-line func-names

      bus.$on('new_parts', (data) => {
        alert(value);
      });
    },
    load() {
    // eslint-disable-next-line func-names
      bus.$on('new_parts', function (data) {
        this.asyncData.data = data;
      });
      const { lineCharts } = this.$refs;
      lineCharts.delegateMethod('showLoading', 'Loading...');
      setTimeout(() => {
        lineCharts.addSeries(asyncData.data);
        lineCharts.hideLoading();
      }, 2000);
    },
  },
};

I want to be able to update my highcharts timeline graph using click events from component-A and update the data coming from the event to component-B everytime click the new button.

1
  • 1
    I dont think this code will work since bus at component A and bus at component B is different. You should catch event from parent component and execute the logic. Commented Jan 13, 2019 at 4:37

4 Answers 4

2

If this is the real code you're using in both components, then it doesn't work because you're creating 2 different buses instead of reusing the same bus for events.

Try pulling it out in a separate file, such as bus.js, then export it and import it in the components where you need to interact with it:

// bus.js
export default new Vue()

// Component A
import bus from './bus'

bus.$emit('new_parts', this.parts.data)

// Component B
import bus from './bus'

bus.$on('new_parts', (data) => {
  alert(value);
})

Let me know if something doesn't make sense.

Sign up to request clarification or add additional context in comments.

1 Comment

I followed your example but now highcharts is not updating when i click and emit the event.
0

The easiest way to handle is to use the this.$root to emit and listen to the event:

To emit the event from component-a:

this.$root.$emit('new_parts', this.parts.data)

To listen to the event on component b:

 mounted() {
            this.$root.$on('new_parts', (data) => {
                //Your code here

            });
        },

Please add the onclick in the mounted method.

Here is a good article on events on Vue: https://flaviocopes.com/vue-components-communication/

Comments

0

Below is the updated code for my highcharts component:

<template>
  <div>
    <vue-highcharts :options="options" ref="lineCharts"></vue-highcharts>
  </div>
</template>

<script>
import VueHighcharts from 'vue2-highcharts';
import { bus } from '../../../main';


export default {

  props: {
    partsdata: {
      type: Array,
    },
  },


  components: {
    VueHighcharts,

  },
  data() {
    return {

      options: {
        chart: {
          type: 'spline',
          title: 'Hassaan',
        },
        xAxis: {
          categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
            'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
        },
        yAxis: {
          title: {
            text: '',
          },
          labels: {
            formatter() {
              return `${this.value}°`;
            },
          },
        },
        tooltip: {
          crosshairs: true,
          shared: true,
        },
        credits: {
          enabled: false,
        },
        plotOptions: {
          spline: {
            marker: {
              radius: 4,
              lineColor: '#666666',
              lineWidth: 1,
            },
          },
        },
        series: [],
      },
    };
  },


  created() {
    bus.$on('new_user', (data) => { this.series = data; });
  },

};
</script>

1 Comment

I am unable to update the highcharts from bus.$emit from the other component.
0

Your last code is almost correct, however here is the wrong part:

Wrong code:

created() {
   bus.$on('new_user', (data) => { this.series = data; });
}

this.series is not referring to series data, instead, you're adding a new property to the whole component object. In your case it should look like that:

Correct code:

created() {
   bus.$on('new_user', (data) => { this.options.series[0].data = data; });
}

I prepared you an online example using highcharts-vue official Highcharts wrapper for VUE which I recommend you. There you will find working code with communication between components.

Demo:
https://codesandbox.io/s/r0qmqjljwq

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.