0

I'm having trouble with this code:

google.charts.load('current', {
    packages: ['corechart', 'line']
});
google.charts.setOnLoadCallback(drawBasic);

function time(dati) {
    var xmlhttp = new XMLHttpRequest();
    xmlhttp.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
            dati = [];
            dati.push(JSON.parse(this.responseText));
            console.log(dati); //logs perfectly fine
            return dati;
        };
    };
    xmlhttp.open("GET", "graph-data.php", true);
    xmlhttp.send();
};
time();
console.log(dati); // logs nothing

function drawBasic(dati) {

    var data = new google.visualization.DataTable();
    data.addColumn('number', 'X');
    data.addColumn('number', 'Prijs');

    console.log(dati); //logs nothing

    data.addRows(dati);

    var options = {
        hAxis: {
            title: 'Time'
        },
        vAxis: {
            title: 'Prijs'
        }
    };

    var chart = new google.visualization.LineChart(document.getElementById('chart_div'));

    chart.draw(data, options);
}

The variables are not defined. How do I define them?

Cœur
  • 37,241
  • 25
  • 195
  • 267
PDek
  • 3
  • 2

1 Answers1

2

You're getting that error because dati is an undeclared variable you're trying to take the value of on Line 17:

console.log(dati);

There is no in-scope dati identifier where that code appears. You have a dati parameter inside your time function, but that's only inside your time function; the line above is outside it.

Once you've fixed that problem, your next problem is covered here: How do I return the response from an asynchronous call? time starts an asynchronous operation that won't be completed yet when time returns.

You also seem to be expecting setOnLoadCallback to pass something to your drawBasic function:

google.charts.setOnLoadCallback(drawBasic);

I can't find the docs for it (!!), but this page's examples don't show the functions called by it accepting any parameters.


Guessing a bit, but I suspect you wanted to do something like this; see inline comments:

// A scoping function so we don't create globals
(function() {
    // Variables for the data and a loaded flag
    var dati = null;
    var loaded = false;

    // A function we can call from both async operations to see if both have completed
    function checkReady() {
        if (dati && loaded) {
            // They're both done, we can draw
            drawBasic(dati);
        }
    }

    // Load charts and get callback when done
    google.charts.load('current', {
        packages: ['corechart', 'line']
    });
    google.charts.setOnLoadCallback(function() {
        loaded = true;
        checkReady();
    });

    // Load our data
    function time() { // <== Note no `dati` parameter, we want to use the variable declared above
        var xmlhttp = new XMLHttpRequest();
        xmlhttp.onreadystatechange = function() {
            if (this.readyState == 4 && this.status == 200) {
                // Fill in the data -- are you sure you really want an array with the data
                // as its only entry?
                dati = [];
                dati.push(JSON.parse(this.responseText));

                // If we're ready, draw
                checkReady();
            };
        };
        xmlhttp.open("GET", "graph-data.php", true);
        xmlhttp.send();
    };
    time(); // Start the data load

    function drawBasic(dati) {

        var data = new google.visualization.DataTable();
        data.addColumn('number', 'X');
        data.addColumn('number', 'Prijs');

        console.log(dati); //logs nothing

        data.addRows(dati);

        var options = {
            hAxis: {
                title: 'Time'
            },
            vAxis: {
                title: 'Prijs'
            }
        };

        var chart = new google.visualization.LineChart(document.getElementById('chart_div'));

        chart.draw(data, options);
    }
})(); // The end of the scoping function, and `()` to invoke it

I'm sure that's not perfect, but hopefully it gets you going the right way.

Community
  • 1
  • 1
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875