Recently at work, one of my friends ran into a problem trying to integrate the Google Visualization API and jQuery. His setup seemed fairly straightforward and it didn’t seem like there would be any problems. He wanted the user to select an option from a dropdown box. That selection would trigger a GET request to fetch some JSON (using the getJSON function of jQuery) from his web server. The result of the request would be passed via getJSON’s callback to Google Visualizations, which would then display some nice charts.

Sounds easy, right?

Unfortunately, when he tested his code in Firefox, the visualization he wanted never showed up. All he saw was an empty iFrame where his chart should have been (Google Visualizations draws certain types of charts using SVG in iFrames).

Puzzled, he started debugging. He quickly confirmed that the proper calls to draw the visualization were being made. Yet somehow, they were just returning an empty iFrame instead of one filled with data. Even more puzzling, his code worked fine when he tested it in Google Chrome, Safari, etc: Firefox was the only browser where it failed!

His next step was to try replacing his chart code with Google’s example code, thinking that maybe the issue was with his data. Amazingly, that chart also failed to display properly! However, it also led him to another discovery: the chart drawing would only fail if it was attempted from within getJSON’s callback function. If the chart was drawn before or after, it would work correctly.

Finally, after several people spent hours wrestling with the problem, one of our fellow employees came up with a solution. He created a closure that would call the correct Javascript functions to draw a graph. Then, he passed that closure to setTimeout with a timeout of 0. It was a fairly elegant workaround: using setTimeout avoided the weird scoping issue (we still don’t understand what the problem was!) and the closure allowed the data to be passed out of the troublesome callback and to the Google Visualization classes. Definitely not the cleanest solution, but very welcome after several hours of wrestling with the problem!