views:

27

answers:

2

Alright, I know questions like this have probably been asked dozens of times, but I can't seem to find a working solution for my project. Recently, while using jQuery for a lot of AJAX calls, I've found myself in a form of callback hell. Whether or not jQuery is too powerful for this project is beyond the scope of this question. So basically here's some code that shows what's going on:

function check_form(table)
{
  var file = "/models/"+table+".json";
  var errs = {};

  var xhr = $.getJSON(file, function(json)
  {
    for (key in json)
    {
      var k = key;
      var r = json[k];
      $.extend(errs, check_item("#"+k,r));
    }
  });
  return errs;
}

And... as you can probably guess, I get an empty object returned. My original idea was to use some sort of onReadyStateChange idea that would return whenever the readyState had finally hit 4. This causes my application to hang indefinitely, though. I need these errors to decide whether or not the form is allowed to submit or not (as well as to tell the user where the errors are in the application. Any ideas?

Edit. It's not the prettiest solution, but I've managed to get it to work. Basically, check_form has the json passed to it from another function, instead of loading it. I was already loading it there, too, so it's probably best that I don't continue to load the same file over and over again anyways. I was just worried about overloading memory. These files aren't absolutely huge, though, so I guess it's probably okay.

+1  A: 

The inline-function in your $.getJSON call will be run when the Ajax call have finished. Do your work inside that (callback) function.

Emil Vikström
That would work, except for I absolutely _must_ eventually return a true or false back to the submit handler. check_form is called by another function that returns `return (countProps(errs) == 0) ? true : false;` It will need to be supplied the data from this function, unless I'm just absolutely missing something.
ashays
You can't do that, because JavaScript is event-driven in it's nature. There are no sleep/wait functions so you cant pause the currently running code. You should try to re-think the logic.
Emil Vikström
Hmmm, I'll see what I can come up with to fix this. I guess I need to go back to the drawing board with a different idea. This one seemed to be working so well, too. :P
ashays
A: 

Your check_form function should accept a callback to execute when the information becomes available later.

function check_form(table, callback)
{
  var file = "/models/"+table+".json";
  var xhr = $.getJSON(file, function(json)
  {
    var errs = {};
    for (key in json)
    {
      var k = key;
      var r = json[k];
      $.extend(errs, check_item("#"+k,r));
    }
    callback(errs);
  });
}

Then, have callers of check_form provide a callback:

var table = getSomeTable();
check_form(table, function(errs)
{
    for (var key in errs)
    {
        var value = errs[k];
        // do something with key/value pair
    }
});
jimbojw