Question

This is a very small-scale project that I am coding myself, so I am able to build all of the resources however I like. I've done research on this site for help on this issue and can't find anything that seems to answer it completely. Please be gentle with me, as I'm still a bit of a novice in learning how to write "good" code. :)


I have some information that I need to get from a database. Let's say the info look like this:

+---------------------+----------------+
| Shape               | Quality        |    <---"fields"
+---------------------+----------------+
| Pointy              | Fair           |    <---"options"
| Round               | Good           |
+---------------------+----------------+

(my info is generated dynamically so that's why I'm just using some example info).

The titles of the columns are the "fields" and the items in the database are the "options".

I need to get each of the fields with all of their options from the database. I want to save those options into an array, and then put all the arrays together in one large Javascript Object that looks something like this: {fieldName:[optionsArray], fieldName:[optionsArray]}. (In our example this would be something like {shape:[pointy,round], quality:[fair,good]}).

To do this I thought the best approach would be to use a for loop that iterates through each of the fields, and calls a GET request to retrieve each of that field's options. So some simple code that will do that is:

var largeObject = {};

for (var i = 0; i < fields.length; i++) {      <---Iterate through the fields
    var fieldName = fields[i];

        $.get("retrieve_field_options.php",      <---Call a GET request to get the options
          {"table":tableName, "field":fieldName},
          function(optionsJSON) {
            //parse the JSON

            var options = [];
            for (i = 0; i < optionsParsed.length; i++) { <---Push the results into an array
              options.push(optionsParsed[fieldName]);
            }
            largeObject[fieldName] = options;      <---Add the array to the full object
          });
 }

But my problem is that the GET request runs asynchronously. So by the time I get down to those last two lines in my "on GET success" function, the outer loop has already changed what the fieldName variable's value is! So it starts the GET request with the right variable value, but a few lines later is always the name of the last field! (in our example, quality).

To me it seems like the easy solution would to just make the GET request synchronous and have the next for iteration not run until the previous results are finished. But everyone says that synchronous requests are bad, and that you should almost always use asynchronous requests. Yet it seems to be screwing over my code in this case, and I have to use AJAX to get my info out of the database.


I know the problem is with how I am structuring the code and not with AJAX itself. I just don't know to structure my code in a way that I can get results from the database and use that info afterward while still keeping my AJAX requests asynchronous? What's the proper solution here? Thanks so much for any help!

Was it helpful?

Solution

If its at all possible, I would modify retrieve_field_options.php to return all the fields with all the options in one call, and if there's too many fields, then have the page accept an input POST param of an array of the field names that you care about. Return everything in one call, as an array of field objects where each object contains an array of their child option objects. This way, you have the field name and the options in the JSON for the JavaScript to parse together.

You'll now be making just the one AJAX call and your synchronous issues will disappear.

(Side note, your question seems valid and well written to me, not sure why it got downvoted.)

OTHER TIPS

You should pivot your table so the columns don't change

+---------------------+----------------+
| Key                 | Option         |
+---------------------+----------------+
| Shape               | Pointy         |
| Shape               | Round          |
| Quality             | Fair           |
| Quality             | Good           |
+---------------------+----------------+

This will simplify your design so you don't need multiple round-trips to the API/database

Licensed under: CC-BY-SA with attribution
scroll top