1

I guess this is a general javascript closure related problem but I am going to use specific example as I cannot wrap my head around it thinking angular-way.

I have an angular component which is using Highcharts library to display a chart. Highcharts can emit event when user selects part of the chart by mouse dragging. The event provides a callback function which takes 2 arguments e.g- function(chartRef, event). I have provided the reference of a class method to the callback function. When the event is emitted by highcharts, inside the method this is bound to the chartRef (callback function scope) and not the angular component class (AppComponent) itself. How can I get a hold of the angular component class instead so that I can use the returned values by the event to my angular application?

import { Chart } from 'angular-highcharts'

export class AppComponent {
  @Output() selection = new EventEmitter<any>()

  chart: Chart;

  ngOnInit() {
    this.init();
  }

  init() {
    let chart = new Chart({
      chart: {
        zoomType: 'x',
        events: {
          selection: this.onChartSelectionEvent,
        },
    },
    // code removed for brevity
    this.chart = chart
    )
  }

  onChartSelectionEvent(chartRef, event) {
    console.log(chartRef.xAxis[0].min) // logs correctly
    console.log(chartRef.xAxis[0].max) // logs correctly
    this.selection.next(chartRef.xAxis[0].max) // doesn't work
    // ERROR Error: Cannot read property 'next' of undefined
    // because `this` refers to the chartRef, not the angular class
  }
}

Stackblitz for the problem

Touhid Rahman
  • 533
  • 5
  • 14

1 Answers1

1

You can use IIFE to store a component reference:

onChartSelectionEvent = (function(self) {
    console.log(self)
    return function(chartRef: any, chartEvent:any){
    console.log(chartRef.xAxis[0].min)
    console.log(chartRef.xAxis[0].max)
    console.log(self)
    }
    // `this` is bound to the chartRef that is emmited by the Highcharts event
    // How can I get a hold of the angular component class (AppComponent) instead?
    //this.selection.next(chartRef.xAxis[0].max)
})(this)

Demo: https://stackblitz.com/edit/angular-kqzyjv?file=src/app/app.component.ts

Sebastian Wędzel
  • 11,417
  • 1
  • 6
  • 16