0

I'm doing something kinda terrible and I know it, but I'm unsure how to avoid the issue.

I have 3 json files, 2 with valid data and 1 that's just empty -- just wanted a valid json file that represented loading nothing. On my site, I have a Twitter Typeahead control. While loading up the sources for my Typeahead, I sometimes need to set both the valid json files mentioned above as sources and sometimes I need to only include one of the valid files and then the second source is set to load the empty file.

Here's the code:

// Typeahead setup
$(function() {

/*
 * TODO: This is synchronous, so not ideal.
 */
var sourceTwoUrl = "data/empty.json";
$.ajax({url: "isSourceTwoUserEnabled.php", async: false,
    success: function(data) {
        if (data == '1') {
            sourceTwoUrl = "data/source2.json"
        }
    }
});

// Setup and instantiate the Bloodhound suggestion engine for source 1
var sourceOne = new Bloodhound({
    datumTokenizer: Bloodhound.tokenizers.whitespace,
    queryTokenizer: Bloodhound.tokenizers.whitespace,
    prefetch: {
        url: 'data/source1.json'
    }
});
sourceOne.initialize();

// Setup and instantiate the Bloodhound suggestion engine for source 2 results,
// using whichever json file was determined above (empty or valid source2.json)
var sourceTwo = new Bloodhound({
    datumTokenizer: Bloodhound.tokenizers.whitespace,
    queryTokenizer: Bloodhound.tokenizers.whitespace,
    prefetch: {
        cache: false,
        ttl: 1,
        url: sourceTwoUrl
    }
});
sourceTwo.initialize();

// Instantiate the actual typeahead control with the 2 data sources loaded above
$('#search .typeahead').typeahead({
        highlight: true,
        hint: true,
        minLength: 2
    },
    {
        name: 'sourceOne',
        source: sourceOne,
        limit: 12
    },
    {
        name: 'sourceTwo',
        source: sourceTwo,
        limit: 6
    }
);

});

This is working perfectly right now, however, I know the synchronous call is bad (and deprecated) and so I'd like to avoid it if possible. Hence the reason this is kinda terrible -- that async: false in my ajax call. I know synchronous calls can lead to a bad user experience, but then again, if the UI and Typeahead load before I get back the result of isSourceTwoUserEnabled.php, it uses the empty.json file every time and therefore we never see any results from source2.json.

So, what's a better way of doing this?

Note, it's okay if source2.json isn't used the very first time after the user enables it; if the better design results in the Typeahead not having the source2.json results until the 2nd time they load it after enabling, that's accepable.

JToland
  • 3,630
  • 12
  • 49
  • 70
  • why not doing with a promise object. use `jquery.when(ajax).then(success, failure);` – Jai Mar 18 '16 at 12:46
  • I've actually never heard of a 'promise object', hence the question. I've spent quite a bit of time "Googling" around for a solution to this, but was having trouble finding exactly what I needed. I'm not new to programming, but to web-specific development, I am. – JToland Mar 18 '16 at 12:50
  • Check http://stackoverflow.com/questions/4368946/jquery-callback-for-multiple-ajax-calls , the idea is do a `$.when(all ajax requests go here).then(function that runs when all are done)` – apokryfos Mar 18 '16 at 12:51
  • Ah, I understand now; thanks for pointing me towards that concept! I have removed the ```async: false``` and resolved it using $.when().done() and it all appears to still be working as expected. – JToland Mar 18 '16 at 14:41

0 Answers0