2

I am trying to take a typical jQuery AJAX call and wrap it in its own function so I can call it with different parameters to make it more dynamic. I seem to be missing something about the success or with callbacks in general. The basic function is to pass JSON to a Google charts implementation. This works if I hardcode the JSON but I want to pick it up out of my REST API. Right now I have this small bit of code:

var getAjax = function (url){
    $.ajax({
        url: url,
        dataType: json,
        success: drawChart
    });
}

var drawChart = function (data) {
    jsonData = data;
    console.log(jsonData);
    // Create our data table out of JSON data loaded from server.
    var jsonDataTable = new google.visualization.DataTable(jsonData);

    // Instantiate and draw our chart, passing in some options.
    //var chartPie = new google.visualization.PieChart(document.getElementById('pie'));
    //var chartBar = new google.visualization.BarChart(document.getElementById('bar'));
    var chartJson = new google.visualization.BarChart(document.getElementById('json'));
    //chartPie.draw(trailerData);
    //chartBar.draw(chewyData);
    chartJson.draw(jsonDataTable);
}

console.log('got here');

getAjax("data/dashboard0");

When I check the console I can see a 200 from jQuery but I get nothing in my window. I also tried using the getAjax(data) to define the function but in my reading I saw I should do it like this but I am not quite sure which approach is the correct one.

Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
eignhpants
  • 1,611
  • 4
  • 26
  • 49
  • 2
    Not sure if this is a typo but, `dataType: json,` should be `dataType: 'json',`. – gen_Eric Oct 21 '15 at 18:28
  • There's nothing immediately wrong with your code, aside from the typo @RocketHazmat mentioned. Have you checked the console for errors? – Rory McCrossan Oct 21 '15 at 18:30
  • Just tested it, and besides the typo the ajax function works just fine, and calls the success handler. – adeneo Oct 21 '15 at 18:30
  • just an observation, `success: drawChart` is not very generic at all. Check out my answer if you want to see a way to do in a more generic sense. You can execute a specific callback per ajax request via `then()` or even passing the callback function in – scniro Oct 21 '15 at 18:35
  • @scniro yes I agree it is not very generic but I am trying to get my basic function down first before making drawChart more flexible. Do I need to declare anything special to use promises? Or is it something i get for free when I import jQuery (which I have to do for google charts anyways). – eignhpants Oct 21 '15 at 18:43

3 Answers3

2

I imagine your syntax error is preventing the code from working...

The dataType should be a string:

dataType: 'json',

Note on response data - If you need the raw data, rather than a parsed data object, you can get that from the raw XHR... no need to unwind the parsed data into another string.

var drawChart = function (data, status, jqXHR) {
    var jsonString = jqXHR.responseText;
    var parsedData = data;
    //...
Fenton
  • 241,084
  • 71
  • 387
  • 401
  • This fixes an immediate problem but now I get a TypeError related to the Google chart library. Which is another issue that needs to be fixed and is separate. Accepted this as an answer. – eignhpants Oct 21 '15 at 18:34
  • This answer doesn't solve your issue, the Google API expects a JSON string not a Javascript Object! – Starmetal Oct 21 '15 at 18:38
  • @kappaismyname I have added a note on that. – Fenton Oct 21 '15 at 18:42
  • was the immediate problem your function not being generic or you had a typo? Hm, perhaps I misread the question – scniro Oct 21 '15 at 18:43
  • 1
    @SteveFenton, now the answer is complete :P Gonna upvote. – Starmetal Oct 21 '15 at 18:46
  • @scniro the immediate problem was that my `success` wasn't working which was related to the typo, but the larger issue is in fact making it more dynamic which is not quite solved. Your solution with promises is not working but I think that is a different problem. In fact I don't know how this is possible but my page won't load at all after trying it, even after reverting the code and rebuilding. – eignhpants Oct 21 '15 at 19:05
  • @eignhpants any errors? Check out [this SO question](http://stackoverflow.com/questions/5436327/jquery-deferreds-and-promises-then-vs-done) for some explanation on the topic. Sorry to jack this answer thread – scniro Oct 21 '15 at 19:14
  • @scniro I cleared the cache in Firefox and that solved the problem. I will have to read up on what happened. No worries on jacking, this has been a good thread (for me at least :)) – eignhpants Oct 21 '15 at 19:16
1

You should instead return a promise in your function, then resolve it via .then(). success: drawChart is not very dynamic. Observe the following...

var getAjax = function (url){
  return $.ajax({ url: url, dataType: 'json' });
}

[...]

getAjax('data/dashboard0').then(function(response) {
    // callback - do drawing tuff
});

console.log('got here before callback')

Check out the jQuery deferred docs for more information

scniro
  • 16,844
  • 8
  • 62
  • 106
  • 2
    You don't *have* to do it in that manner. There's nothing inherently wrong with the approach in the OP. – Rory McCrossan Oct 21 '15 at 18:30
  • 1
    this doesn't answer the problem OP is having – charlietfl Oct 21 '15 at 18:31
  • Yea I guess it was a typo -__- However, if wanting to abstract a generic ajax wrapper, this seems suitable. `success: drawChart` does not seem very "dynamic" thanks for the downvote btw – scniro Oct 21 '15 at 18:32
  • I agree this is a nicer solution as it allows the callback to be defined externally. Just FYI downvote isn't mine. – Rory McCrossan Oct 21 '15 at 18:33
  • I am still wrapping my head around callbacks, and I wanted to ask: on the `.then(function(response) {}` what does `response` represent? Is it something returned from `then()` or is it something I write myself? Or does it come from the body of my statement? – eignhpants Oct 21 '15 at 18:45
  • `response` is an object containing what is returned from your ajax call - this is where you're find any data you are returning. You can log it out to see all whats in there. You get `then()` for free - it's a function that is on the object when you `return $.ajax` in your `getAjax` function - known as a promise – scniro Oct 21 '15 at 18:48
0

The success's method first argument is parsed. If you need a JSON string then you have to JSON.stringify(responseData) which will return a JSON string.

Even if you set dataType: 'json', jQuery will still parse the response.

Please read the jQuery Docs for dataType:

dataType: "json": Evaluates the response as JSON and returns a JavaScript object. Cross-domain "json" requests are converted to "jsonp" unless the request includes jsonp: false in its request options. The JSON data is parsed in a strict manner; any malformed JSON is rejected and a parse error is thrown. As of jQuery 1.9, an empty response is also rejected; the server should return a response of null or {} instead. (See json.org for more information on proper JSON formatting.)

Starmetal
  • 740
  • 6
  • 14