'Javascript closure with async ajax data initializer
I'm stuck trying to figure out how to create a closure API with an ajax data initializer.
My goal is to initialize a countries object (hash of hashes of country information) via an async ajax call (this initialization happens once on page load), then this data is encapsulated in a closure so that only two APIs are visible: one getCountryInfo() that just gets country's info and countryAutoComplete() that is an api for jquery-ui's autocomplete functionality.
Question: I have the two bits of code, but I do not know how to perform the ajax request and have its data available for the closure and be able to return the userdb API to the application. I can do any 2/3, but I'm not sure how to tie it all together.
I have javascript and jquery at my disposal.
Here are the two bits of code. (This is a simplified example, cut down for this question. I've tried to avoid syntax errors in this excerpt, but understand this is not the actual code.)
// populate the data initially
timestamp = localStorage.getItem('all_countries_time') || 0;
$.getJSON(
"/api",
{
item: 'countries',
timestamp: timestamp
},
function(data)
{
// !! I need this data set before I can run the code below
if (data.timestamp != '0')
{
localStorage.setItem('all_countries_time', data.timestamp);
localStorage.setItem('all_countries', JSON.stringify(data.countries));
}
}
);
And
// Create the API in a closure
var countrydb = (function() {
let countries = JSON.parse(localStorage.getItem('all_countries'));
// ! I don't think I can return this API from a response() or when().then() clause. But I could be wrong.
return {
getCountryInfo: function(country)
{
return countries[country]
},
countryAutoComplete: function(prefix, callback)
{
let cmatch = [];
for (const [name, cinfo] of Object.entries(countries)) {
if (name.startsWith(prefix) || cinfo.intlcode.startsWith(prefix) ) {
cmatch.push(userinfo);
}
}
callback(cmatch);
}
};
});
let cdb = countrydb();
let canada = cdb.getCountryInfo('Canada');
$("#countries_select").autocomplete(source: cdb.countryAutoComplete);
Update
I never did find a solution. In the end I have two globals countries and countries_initialized. Setups of getCountryInfo() and countryAutoComplete() functions come after a successful poll-and timer for countries_initialized being set.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
