[Chartjs]-Javascript object from string

1👍

You are using eval for creating an array of objects:

s1 = '{value:25, color:"red"}';
s2 = '{value:5, color:"blue"}';
s3 = '{value:25, color:"palegreen"}';
s4 = '{value:10, color:"darkcyan"}';
s5 = '{value:35, color:"wheat"}';
var pieData = [ s1+s2+s3+s4+s5 ];

The above code snippet is a wrong way of doing this. Here you shouldn’t create a string representation of an object (those are not valid JSON strings) when you need a real object. What you should do is:

var s1 = {value:25, color:"red"};
var s2 = {value:5, color:"blue"};
var s3 = {value:25, color:"palegreen"};
var s4 = {value:10, color:"darkcyan"};
var s5 = {value:35, color:"wheat"};
var pieData = [ s1, s2, s3, s4, s5 ];

Now pieData is an array of objects. Done!

2👍

I have fixed this. The key was understanding that eval() must not ever be used, under any circumstances. (At my present skill level, at least)

Aside from the ajax injection, and JavaScript code being injected with it, here’s what I was trying to do. I had these values in variables:

cu = 3;
py = 5;
fs = 7;
qz = 9;
ch = 11;
am = 13;
mi = 15;
mo = 17;

I had to create an array that was part text/part variable (I thought…). So, I tried this:

pDat = ['{value:'+cu+'}, {value:'+py+'}, {value:'+fs+'}, {value:'+qz+'}, {value:'+ch+'}, {value:'+am+'}, {value:'+mi+'}, {value:'+mo+'}'];

That didn’t work. So I tried:

eval('pDat = [{value:'+cu+'}, {value:'+py+'}, {value:'+fs+'}, {value:'+qz+'}, {value:'+ch+'}, {value:'+am+'}, {value:'+mi+'}, {value:'+mo+'}']');

That worked for the array, but not for the object.

With the good advice from Vohuman, guest271314, epascarello and other good souls, I went back to the drawing board and refactored the code so that I could just do this:

(And it worked for everything – I was even able to add the variables with the color codes):

pDat = [{value:cu, color:CuCol}, {value:py, color:PyCol}, {value:fs, color:FsCol}, {value:qz, color:QzCol}, {value:ch, color:ChCol}, {value:am, color:AmCol}, {value:mi, color:MiCol}, {value:mo, color:MOCol}];

oOpt = {
    annotateDisplay : true,
    segmentShowStroke : false,
    segmentStrokeColor : "white",
    segmentStrokeWidth : 1,
    percentageInnerCutout : 0,
    animation: false,
    animationSteps : 100,
    animationEasing : "easeOutQuart",
    animateRotate : true,
    animateScale : false,
    legendTemplate : '<ul class="<%=name.toLowerCase()%>-legend"><% for (var i=0; i<segments.length; i++){%><li><span style="background-color:<%=segments[i].fillColor%>"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>'
};

var ctx = document.getElementById("pieChart").getContext("2d");
updateChart(ctx,pDat,pOpt,true,false);

Note:

FWIW, CuCol, PyCol etc are just vars that look like this:

CuCol = '#ffe382';
PyCol = '#1bb3a5';
etc

1👍

Note, adjusted double quotes at <ul> string attributes to single quotes .

Try using String.prototype.split() , Array.prototype.map() , String.prototype.replace() with RegExp /(^[a-zA-Z]+)(?=\s|:)/g to match characters a-z case insensitive followed by space character or colon character ":" property of object string ; JSON.stringify() , JSON.parse()

pieO  = 'annotateDisplay : true,';
pieO += 'segmentShowStroke : false,';
pieO += 'segmentStrokeColor : "white",';
pieO += 'segmentStrokeWidth : 1,';
pieO += 'percentageInnerCutout : 0,';
pieO += 'animation: false,';
pieO += 'animationSteps : 100,';
pieO += 'animationEasing : "easeOutQuart",';
pieO += 'animateRotate : true,';
pieO += 'animateScale : false,';
pieO += 'legendTemplate : "<ul class=\'<%=name.toLowerCase()%>-legend\'><% for (var i=0; i<segments.length; i++){%><li><span style=\'background-color:<%=segments[i].fillColor%>\'></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>"'

pieO = pieO.split(",").map(function(val, index) {
    val = val.replace(/(^[a-zA-Z]+)(?=\s|:)/g, function(match) {
      return JSON.stringify(match)
    });
    return JSON.parse("{" + val + "}")
});

console.log(pieO)

Leave a comment