First8 staat voor vakmanschap. Al onze collega’s zijn een groot aanhanger van Open Source en in het bijzonder het Java-platform. Wij zijn gespecialiseerd in het pragmatisch ontwikkelen van bedrijfskritische Java toepassingen waarbij integratie van systemen, hoge eisen aan beveiliging en veel transacties een belangrijke rol spelen. Op deze pagina vind je onze blogs.

Asynchronous Google Chart Data With jQuery in Grails

Google Charts is an awesome platform to create great-looking interactive charts, from simple scatter plots to timelines or

I needed a way to create the required data for a chart on the server-side, instead of in-lining it in the JavaScript itself — as seen in many of the examples. 

Why asynchronously?

Although in the example below we’re using a small hard-coded dataset, for which there’s no real need to have this done asynchronously, this might not always be the case in the real world. Loading in data asynchronously improves the user experience especially if calculating or getting the data for the chart might take significant time. E.g. the page containing the charts is displayed quickly in the browser — while the actual graphs are rendered when the data comes in.

Sometimes you might even have multiple charts on a page, which leans even more to a situation where the page response time can become too lengthy if we have to wait on all graph data to be fetched or computed first before rendering the page.

So I took the PHP example and re-created it in a Grails way. I’m also taking care of exceptional situations and logging errors on the client side. This is just an example which works for me – there might be other approaches.


For simplicity’s sake I just took the example code quite literally and put it in the head section of a Grails GSP page.

For those wondering whether or not they can download the JS files and have it processed with the Asset Pipeline plugin. The answer is: no. Per the FAQ:

Sorry; our terms of service do not allow you to download and save or host the google.load or google.visualization code.

So we have to include the jsapi JavaScript in the head – which you can do on your specific chart page (as seen below) or in your main.gsp layout. If your Grails application by default is still shipped with jQuery as a dependency, then you don’t need to include it explicitly on your page ofcourse – but I have left the jquery.min.js line below intact for now.

The $.ajax statement is jQuery’s way of performing an asynchronous HTTP (Ajax) request. In the url I’m creating a link – with Grails’ createLink-tag – to the ChartController and toppings action responsible for giving me the JSON chart data.

Initially you won’t see a thing when the page is rendered. However, as soon as the <script> block is encountered, the browser interprets it, loads the Google libraries which invokes our callback function drawChart. This callback has jQuery make a new request to fetch the chart data. The response of the request is loaded into a variable jsonData which is passed to the constructor of Google’s own DataTable JS class.

The chart is drawn and the HTML div – with id chart_id – is updated with a chart.


The JSON is the result of calling controller action below:

It’s all Maps in Maps in Lists etc. in Groovy syntax. If you’re wondering what these “c” and “v” values mean; they’re the essential properties for defining an array of cells in that row and defining the value for that cell. There are more parameters, which you can use to tweak formatting and more.

If you’ve got the nesting right, just using Grails’ grails.converters.JSON will do the trick to get this structure rendered as valid JSON, something our Google Chart JavaScript understands very well.

By accessing your url directly in the browser on e.g.

you can inspect the raw JSON:

You could create some helper methods to make creating this data somewhat easier. E.g. to remove the repetition, you could use a Groovy closure like this:

Upon accessing the page I successfully see my pie chart.


Not done yet

However, I’m also getting a JavaScript warning:

Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user’s experience. For more help, check

Seems the example I took still had async: false in place. Overlooked it. Just set async explicitly to true (or leave it out – since it defaults to true) to make it do its call asynchronously.

Unfortunately, this causes the AJAX call not to block any more and immediately pass jsonData to the DataTable constructor – even before any data actually came back from the controller. At this point jsonData is undefined and the Google Chart fails with an error “Table has no columns”.


To properly fix this in jQuery the documentation on jquery.ajax suggests to use the promises of the jqXHR object. We have a few, such as done – a callback which is fired when the operation successfully completed.

If we’re in the callback, we know we have the JSON data. Here’s after the changes:


Exceptional situations

But where again not there yet. What if the calculation of the chart data fails due to some reason? E.g. ChartController fails at run-time? Right now, in this case we’re getting an HTTP 500 (“Internal Server Error”) for that asynchronous request and consequently NO chart is drawn – just an empty space on the page. In these exceptional situations we could at least inform the user where his chart has gone to provide a better user experience.

We can use the fail promise for this. It’s a special method called when the request is “rejected”. It gets passed a few parameters, such as jqXHR, textStatus and errorThrown, but there’s nothing really interesting to get from these right now when an Internal Server Error occurs. The reason of failure can be anything.

So, things could be as simple as displaying an alert.

This is not really a “better user experience” of course 🙂 We need a way to leverage the existing error reporting, such as the earlier error when the chart failed with “Table has no columns”. The Google Chart API docs describe several functions to help you display error messages to users.

It seems there are some static function in the google.visualization.errors namespace we can leverage, such as addError. This function accepts a minimum amount of parameters: the container, our chart DOM element, and a message, so it can display an error block in the visualization.

Let’s put it to use:

I’ve extracted the chart div element to a higher-level to be able to re-use it in both done() and fail() promises.

The error would now be displayed where the chart would be:


Development tip

You can optionally use the google.visualization.dataTableToCsv helper function to display the loaded data for development purposes in the browser’s console.

That’s it. Happy charting!

Original article