Search code examples
javascriptcanvasjs

Uncaught TypeError: chart.render is not a function


I'm trying to pass the string value from my controller to my javascript to render my chart thru on click of a button.

In my controller I query the needed data and echo the return value, below is the value

 new CanvasJS.Chart("myChart", {
                    animationEnabled: true,
                    theme: "light2",
                    title:{
                        text: "Devices"
                    },
                    axisY: {
                        title: "From"
                    },
                    legend: {
                        cursor:"pointer",
                         itemclick : toggleDataSeries
                    },
                    toolTip: {
                        shared: true,
                        content: toolTipFormatter
                    },
                    data: [
                        {
                                type: "bar",
                                showInLegend: true,
                                name: "A",
                                dataPoints: [{ y: 2, label: "Keyboard" },{ y: 13, label: "Laptop" }]},{
                                type: "bar",
                                showInLegend: true,
                                name: "B",
                                dataPoints: [{ y: 1, label: "Keyboard" },{ y: 0, label: "Laptop" }]}
                    ]
                })

I used ajax to get the value above like below:

         var return_first = function () {
          var tmp = null;
          $.ajax({
            'async': false,
            'type': "POST",
            'global': false,
            'dataType': 'html',
            'url': base_url + 'my_controller/dChart',
            'data': {
                'dev_fil' : $("#dev_fil").val()
            },
            'success': function (data) {
                tmp = data;
            }
        });
        return tmp;
    }();

And then I will assign it to a variable and render() it

 var chart = return_first;
 chart.render();

But it keeps on returning and error Uncaught TypeError: chart.render is not a function

I tried to just render it normally and not from ajax it displays the chart but I need to change the value of the chart when submitting a device name.

Thank you in advance for the help.

---UPDATE---

I tried to pass only the values inside the data[] and call the render() inside the success.

var return_first = function () {
          var tmp = null;
          $.ajax({
            'async': false,
            'type': "POST",
            'global': false,
            'dataType': "html",
            'url': base_url + 'my_controller/dChart',
            'data': {
                'dev_fil' : $("#dev_fil").val()
            },
            'success': function (data) {
                console.log(data)
                tmp = new CanvasJS.Chart("myChart", {
                    animationEnabled: true,
                    theme: "light2",
                    title:{
                        text: "Device Replacement"
                    },
                    axisY: {
                        title: "Outlets"
                    },
                    legend: {
                        cursor:"pointer",
                         itemclick : toggleDataSeries
                    },
                    toolTip: {
                        shared: true,
                        content: toolTipFormatter
                    },
                    data: [data]
                });
                tmp.render();
            }
        });
        return tmp;
    }();

I'm having an error

Uncaught TypeError: Cannot use 'in' operator to search for 'name' in {
                                type: "bar",
                                showInLegend: true,
                                name: "AA",
                                dataPoints: [{ y: 13, label: "Laptop" }]}

Its at canvas.minjs


Solution

  • The data comes through as a string, so you are assigning tmp to a string, which does not have the function render(). You need to eval() the string to have it execute the string as code, which would then create your object:

    'success': function (data) {
                tmp = eval(data);
            }
    

    Just a note, eval is generally not the best way to do things. Here you might consider returning just the json settings in your API and creating the object in the success:

    var return_first = function () {
          var tmp = null;
          $.ajax({
            'async': false,
            'type': "POST",
            'global': false,
            'dataType': 'json', // notice we changed to 'json' here
            'url': base_url + 'my_controller/dChart',
            'data': {
                'dev_fil' : $("#dev_fil").val()
            },
            'success': function (data) {
                tmp = new CanvasJS.Chart("myChart", data);
            }
        });
        return tmp;
    }();
    

    --- UPDATE ---

    Based on your most recent code, you want your server side to be returning this:

    [
                            {
                                    type: "bar",
                                    showInLegend: true,
                                    name: "A",
                                    dataPoints: [{ y: 2, label: "Keyboard" },{ y: 13, label: "Laptop" }]},{
                                    type: "bar",
                                    showInLegend: true,
                                    name: "B",
                                    dataPoints: [{ y: 1, label: "Keyboard" },{ y: 0, label: "Laptop" }]}
                        ]
    

    and your client-side code will look like this:

    var return_first = function () {
              var tmp = null;
              $.ajax({
                'async': false,
                'type': "POST",
                'global': false,
                'dataType': "json", // note we set json here
                'url': base_url + 'my_controller/dChart',
                'data': {
                    'dev_fil' : $("#dev_fil").val()
                },
                'success': function (data) {
                    console.log(data)
                    tmp = new CanvasJS.Chart("myChart", {
                        animationEnabled: true,
                        theme: "light2",
                        title:{
                            text: "Device Replacement"
                        },
                        axisY: {
                            title: "Outlets"
                        },
                        legend: {
                            cursor:"pointer",
                             itemclick : toggleDataSeries
                        },
                        toolTip: {
                            shared: true,
                            content: toolTipFormatter
                        },
                        data: data // notice data is not wrapped in brackets because it's already an array
                    });
                    tmp.render();
                }
            });
            return tmp;
        }();