3

I have a page with a number of charts generated from a Google spreadsheet.

Typical code looks like this:

var url = "http://my.googlespreadsheet.com/tq?argumentshereblahblahblah";
// create and send off the query
var query = new google.visualization.Query( url );
query.send( handleQueryResponse );

function handleQueryResponse(response) {
    // omitted code to handle errors
    // create new chart object, specify location in page
    var chart = new google.visualization.BarChart( document.getElementById('chart-' + i));
    // draw chart
    chart.draw( data, {} );
}

As I have several charts on the page, I'd like to create them programmatically without having to have x functions that all look the same with just the chart location and title differing. I've set up an array of spreadsheet references which I iterate through, passing each one to a function that runs the above code: creating a query, sending it off, handling the response. What I want to do is pass an extra argument to the handleQueryResponse callback so that I can specify where on the page the graph should go. I can't work out a way to get my variable into handleQueryResponse, though. If I do this:

// array of spreadsheet refs
var quArr = ['gid=2&range=D2%3AE10&headers=-1','gid=2&range=D15%3AE19&headers=-1', (etc.) ];
var base_url = "http://my.googlespreadsheet.com/tq?";
var i; // iterator

// iterate through the spreadsheet refs and send off the queries for each
for (i = 0; i < quArr.length; i++){
    var url = q_base + quArr[i];
    var query = new google.visualization.Query( url );
    query.send( handleQueryResponse );
}

// deal with the responses
function handleQueryResponse(response) {
    // omitted code to handle errors
    // get the data from the response
    var data = response.getDataTable();
    // create new chart object, specify location in page
    // anchors in the page correspond to where the chart should go
    var chart = new google.visualization.BarChart( document.getElementById('chart-' + i));
    chart.draw( data, { extra args } );
}

...the asynchronous nature of the returned responses means that the iterator isn't the same value as when I sent the request.

Extra info from the API docs:

send(callback)

Sends the query to the data source. callback should be a function that will be called when the data source responds. The callback function will receive a single parameter of type google.visualization.QueryResponse. Return value: none

Questions:

1) does what is written in the API docs about query.send( callback ) essentially mean that I can't alter the callback to take extra arguments?

2) can anyone suggest another way around this problem?

i alarmed alien
  • 9,412
  • 3
  • 27
  • 40

1 Answers1

3

Just worked out the answer to my own question - woohoo! Should have persevered a bit longer. ;)

In case it is useful for anyone else, I created a new function to perform the query and used a closure for the callback. Here's the reorganized code:

for (var i = 0; i < quArr.length; i++){
    var url = q_base + quArr[i];
    var query = new google.visualization.Query( url );
    doQuery(query, i);
}

function doQuery(q, it){
    q.send( function(response){
        // omitted error handling code
        var data = response.getDataTable();
        var chart = new google.visualization.BarChart( document.getElementById('chart-' + it));
        chart.draw( data, { other args } );
    });
}
i alarmed alien
  • 9,412
  • 3
  • 27
  • 40