0

i've created an object that contains the names of several objects and the names of functions associated with creating new objects, in this case, charts.

var oCharts = [{
    nchart: "chart1",
    fchart: "makeChart1"
  },
  {
    nchart: "chart2",
    fchart: "makeChart2"
  },
  {
    nchart: "chart3",
    fchart: "makeChart3"
  }
]

"nchart" is the variable representing the chart to be destroyed. "fchart" is the variable representing the function to create a new chart.

If i do it manually, like this, it works

if(typeof chart1 != undefined ){
  chart1.destroy();
  makeChart1();         
}   

If i iterate over oCharts, it doesn't work. I get "Object doesn't support property or method 'destroy'" and, of course, it never gets far enough to run makeChart(). (i'm not even sure I'm calling that correctly.)

$(oCharts).each(function(i,v){
  var myChart = [this.nchart];
  var makeChart = this.fchart;

  if(typeof myChart != undefined ){
    myChart.destroy();
    makeChart();            
  }
});

the functions to make charts are simply...

function makeChart1(){
 // do stuff
}

function makeChart2(){
 // do other stuff
}

function makeChart3(){
 // do different stuff
}

Can someone please tell me what I'm doing wrong? It would be very much appreciated!

Chris G.
  • 329
  • 4
  • 17
  • How are the functions defined ? If will have to evaluate dynamically using `eval` to invoke the functions by the string instead of its reference which is a bad idea. You are running into the error as you are using `()` on a `string` `typeof myChart` is a `string` and only functions have the properties to invoke it – Sushanth -- Apr 24 '19 at 18:23
  • how you are destroying the charts ??? – vaku Apr 24 '19 at 18:28
  • the charts are made using chart.js. chart1.destroy() is how you destroy them to create a new one with the same ID. – Chris G. Apr 24 '19 at 18:29
  • Your expression `typeof myChart != undefined` always will be true because `typeof variable` always return `string` type and you should compare it with stringified value of `undefined` i.e. `typeof myChart !== 'undefined'` Also, before this expression you create a variable ` var myChart = [this.nchart]; ` `typeof myChart` always will return 'object'. To prevent you need just assign `this.nchart` to `myChart` – Sergey Volkov Apr 24 '19 at 19:15
  • Apologies, Sergey. But, if myChart has not been created yet, typeof myChart will be undefined, and, therefore, cannot be destroyed. I'm trying to pass the ID of the chart into the condition and, if the object with that ID is defined, then destroy it. – Chris G. Apr 24 '19 at 19:26

3 Answers3

1

Two things to note:

1) The keyword you're looking for is not destroy, it's delete. And it's not a function, it's a operator used as such:

let a = {b: 3, c: 4};
delete a.b;
console.log(a);

2) Using delete is not necessary, as you'll be overwriting nchart in makeChart1.

Here's some edits to get you started:

let makeChart1 = () => {
  // do stuff
  return 1;
};

let makeChart2 = () => {
  // do stuff
  return 2;
};

let makeChart3 = () => {
  // do stuff
  return 3;
};

let oCharts = [{
  nchart: "chart1",
  fchart: makeChart1
}, {
  nchart: "chart2",
  fchart: makeChart2
}, {
  nchart: "chart3",
  fchart: makeChart3
}];

oCharts.forEach(chart =>
    chart.nchart = chart.fchart());

console.log(oCharts);
junvar
  • 11,151
  • 2
  • 30
  • 46
1

i'm sure this can be done in a smarter way but this should work on your example: i assume chart1, chart2, chart3 are chart instances already created as var chart1 = new Chart(ctx, config)

$(oCharts).each(function(i,v){
  var myChart = this.nchart;
  var makeChart = this.fchart;

  if( myChart == "chart1" ){
    chart1.destroy();
    makeChart1();
  }
  if( myChart == "chart2" ){
    chart2.destroy();
    makeChart2();
  }
  if( myChart == "chart3" ){
    chart3.destroy();
    makeChart3();
  }
  }
);

update for dynamically use: check this out (How do I call a dynamically-named method in Javascript?)

$(oCharts).each(function(i,v){
  var myChart = this.nchart;
  var makeChart = this.fchart;


    self[myChart].destroy();
    self[makeChart]()


  }
);

hope this help.

Alex Ciu
  • 148
  • 1
  • 6
  • that's kinda what I'm going for, Alex. But I didn't want to have to create separate IF statements for each chart. That's why I'm putting their id's in the oCharts object. So I can iterate over oCharts, destroy the current chart, create a new one, and move on. – Chris G. Apr 24 '19 at 19:04
  • @ChrisG. check this update and let me know if works – Alex Ciu Apr 24 '19 at 19:30
  • oooooh! I'm gonna give that a go. – Chris G. Apr 24 '19 at 20:31
0
var chart1 = {destroy:function(){console.log('chart1')}}
var chart2 = {destroy:function(){console.log('chart2')}}
var chart3 = {destroy:function(){console.log('chart3')}}
function makeChart1(){
console.log('make chart 1');
}

function makeChart2(){
 // do other stuff
  console.log('make chart 2');
}

function makeChart3(){
 // do different stuff
  console.log('make chart 3');
}

var oCharts = [{
    nchart: chart1,
    fchart: makeChart1
  },
  {
    nchart: chart2,
    fchart: makeChart2
  },
  {
    nchart: chart3,
    fchart: makeChart3
  }
]
$(oCharts).each(function(i,v){

  var myChart = this.nchart;
  var makeChart = this.fchart;

  if(typeof myChart != undefined ){
    myChart.destroy();
    makeChart();            
  }
});
Vishnu
  • 897
  • 6
  • 13