0

I want to call both a javascript function and a typescript function from the same event. It is a onClick event in a chart. I am relatively new to typescript and angular, so i dont know if what i am doing is even possible.

The problem is: I need to call a javascript function for getting a activated bar in the chart, and the typescript function to open a dialog in the angular component.

    onClick: function(evt){

      console.log(this);//<-- returns chart

      bar: () => {console.log(this)}; //<-- here I try to get this as component
      bar(); // <--doesnt work

      //console.log(document.getElementById('myChart'));
  }

Maybe bette if i show the whole thing.

  public barChartOptions = {
    scaleShowVerticalLines: false,
    responsive: true,
    events: ['mousemove', 'mouseout', 'click', 'touchstart', 'touchmove'],
    onHover: console.log('onHover'),

    onClick: function(evt){
      //console.log(evt); Mouse Event
      console.log(this);
      const getFirst = array => console.log(this);
      console.log(getFirst);
      //bar: () => {console.log(this)};
      //bar();
      //console.log(document.getElementById('myChart'));
  },
    /*
    onClick : (evt, datasets) => {
      //let self = this;
      //console.log(self);
      if(datasets.length > 0){
        this.openDialog();
        console.log(this);
        console.log(this.barChart);
      }
    },*/
    scales: {
      xAxes: [{
        stacked: true
      }],
      yAxes: [{
        stacked: true
      }]
    },
    legend: {
      display: true,
      position: 'right'
    },
    tooltips: {
      enabled: true,
      mode: 'point'
    }
  };

this is my html template:


  my-bar-dialog works!
  <div>
    <div style="display: block">
      <canvas baseChart
              id="myChart"
              [datasets]="barChartData"
              [labels]="barChartLabels"
              [options]="barChartOptions"
              [legend]="barChartLegend"
              [chartType]="barChartType">
      </canvas>
    </div>
  </div>

  <button mat-raised-button (click)="openDialog()">Pick one</button>
  <button (click)="openDialog()">Pick one</button>

Now, the thing is i have two different "this": 1)

    onClick: function(evt){
      let that = this;
      let bar=()=> {console.log(that.this)};
      bar();

  },

2)

    onClick : (evt, datasets) => {
      if(datasets.length > 0){
        console.log(this);
      }
    },

1 returns a char, 2 returns the component. But i need both of them in the same Event/function as i need to call chartjs api functions and i need to call a function from my component.

And here my component

import { Component, OnInit, Inject } from '@angular/core';
import {MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog';
import { BarChartService } from '../bar-chart.service';
import { barChartClass } from '../barChartClass';

declare var foo: Function;

@Component({
  selector: 'app-my-bar-dialog',
  templateUrl: './my-bar-dialog.component.html',
  styleUrls: ['./my-bar-dialog.component.css'],
})
export class MyBarDialogComponent implements OnInit {

  client: string;
  tenant: string;

  constructor(public dialog: MatDialog, private barChartService: BarChartService) {
    foo();
  }
  //First BarChart
  barChart: barChartClass;
  public barChartLabels: any;
  public barChartType: any;
  public barChartLegend: any;
  public barChartData: any;

  getBarChart(): void {
    this.barChartService.getMockBarChart().subscribe(
      barChart => this.barChart = barChart
    );
    this.barChartData = this.barChart.barChartData;
    this.barChartLabels = this.barChart.barChartLabels;
    this.barChartType = this.barChart.barChartType;
    this.barChartLegend = this.barChart.barChartLegend;
  }

  public barChartOptions = {
    scaleShowVerticalLines: false,
    responsive: true,
    events: ['mousemove', 'mouseout', 'click', 'touchstart', 'touchmove'],
    onHover: console.log('onHover'),


    onClick: function(evt){
      //console.log(evt); Mouse Event
      //console.log(this);
      let that = this;
      //bar: () => {console.log(this)};
      let bar=()=> {console.log(that.this)};
      bar();
      //bar();
      //console.log(document.getElementById('myChart'));
  },
    /*
    onClick : (evt, datasets) => {
      //let self = this;
      //console.log(self);
      if(datasets.length > 0){
        this.openDialog();
        console.log(this);
        console.log(this.barChart);
      }
    },*/
    scales: {
      xAxes: [{
        stacked: true
      }],
      yAxes: [{
        stacked: true
      }]
    },
    legend: {
      display: true,
      position: 'right'
    },
    tooltips: {
      enabled: true,
      mode: 'point'
    }
  };

  openDialog(): void {
    const dialogRef = this.dialog.open(DialogData, {
      width: '250px',
      data: {client: this.client, tenant: this.tenant}
    });

    dialogRef.afterClosed().subscribe(result => {
      console.log('The dialog was closed');
      this.client = result;
    });
  }
  ngOnInit() {
    this.getBarChart();
  }
}

@Component({
  selector: 'dialog-data',
  templateUrl: 'dialog-data.html',
  styleUrls: ['dialog-data.css']
})
export class DialogData {

  constructor(
    public dialogRef: MatDialogRef<DialogData>,
    @Inject(MAT_DIALOG_DATA) public data: DialogData) {}

  onNoClick(): void {
    this.dialogRef.close();
  }

}

2
  • before accessing your function assign this to some other variable like var that = this; and inside your function this will point to chart and that will point to your component Commented Jun 19, 2019 at 11:33
  • Post html template with your chart Commented Jun 19, 2019 at 11:42

2 Answers 2

2

What you're doing with the bar and the colon in the function is that you're trying to describe its type rather to declare it. So if you want to actually declare the function, do this:

onClick: function(evt) {

    console.log(this);//<-- returns chart

    let bar = () => { console.log(this) };
    bar();

    //console.log(document.getElementById('myChart'));
  }

if you want to describe and declare it, do this:

  onClick: function(evt) {

    console.log(this);//<-- returns chart

    let bar: () => void = () => { console.log(this) }; //<-- here I try to get this as component
    bar(); // <--doesnt work

    //console.log(document.getElementById('myChart'));
  }
Sign up to request clarification or add additional context in comments.

Comments

0

before using the chart in component assign this to some other variable like

var that=this

then in your chart

 onClick: function(evt){

      console.log(this);//<-- returns chart

   let   bar= () => {console.log(that)}; //<-- that should have your component refrence

  }

Stackblitz demo

6 Comments

@ if you can create stackblitz for your application than i can show you working example
as @smytt said it should be bar=()=> not bar:()=>
a stackblitz is a bit hard to implement as i am using chartjs and the charts are created dynamically but i will try, further i tried as you suggested and now my bar() function works but i returns the same thing as my console.log(this) maybe i explained it bad i will edit my post a bit.
where are using public barChartOptions = { in consturctor? Did you try var that=this before this(public barChartOptions = {) line? and use that inside function
|

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.