-1

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!

2
  • Why the downvote? Have I asked something wrong?
    – Guy
    Dec 19 '19 at 0:59
  • Have retrieve_field_options.php return the field name and use that to index into largeObject. Keep track of running AJAX requests and, when all have completed, update your select options. You're dealing with callback scope issues. There are multiple ways to handle it but I've outlined what I think is the easiest.
    – Dan Wilson
    Dec 19 '19 at 1:55
2

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.)

2
  • Okay, sounds good, I'll implement this! In general, is it best to make as few AJAX calls as possible and then parse through the results in the Javascript instead?
    – Guy
    Dec 21 '19 at 20:58
  • Hmmm I suppose that's not a bad principle to stick with as you are getting more comfortable with AJAX.
    – Graham
    Dec 23 '19 at 13:42
-2

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

1
  • 1
    Even if I do that, though, how will it solve my AJAX problem? Are you saying I should do that so that I can perform one database query and then sort through the results in the Javascript?
    – Guy
    Dec 18 '19 at 23:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.