I have written a Javascript function to retrieve JSON data from either a server or local files, in any browser. This code digests JSON data from either: (a) an XMLHttpRequest response, or (b) an imported script variable.
For the latter case, this code expects the variable 'JSONdata'. Instead of putting it inline in two (or more) places, it is initialised as a global constant JSCRIPTVAR. This is for legibility and maintenance - to change if the data file uses a different value. You'll see the code uses an eval function to extract the (pointer to our) JSON data - a bit too close to the actual data for my comfort. My question is, how do I read the value of the primitive variable 'JSONdata' via its alias JSCRIPTVAR without using (the dreaded) eval function?
I have tried closures and other methods described here (Reference a Javascript variable by a text alias) but am unable to get the JSON data, only the variable name or 'undefined'.
var JSCRIPTVAR = "JSONdata"; // any variable name less than 10 characters or less
function digestJSON(response, JSONobjName) {
if (typeof response == 'string')
JSONstring = response;
else if (typeof JScriptVar !== 'undefined' && typeof JSCRIPTVAR.valueOf() !== 'undefined')
JSONstring = eval(JSCRIPTVAR.substring(0, 10)); // ensure that we don't take in any malicious code
try {
// this method assigns the JSON data to a global object using JSONobjName, so can support multiple JSON objects
window[JSONobjName] = JSON.parse(JSONstring); // Parse JSON string into object - IE 8+ supports JSON.parse()
console.log("Successfully digested JSON. Data is now available via DOM methods.");
} catch (e) {
alert("Error parsing the '" + JSONobjName + "' file'. Check that the file is properly formatted.");
console.error("JSON parsing error: ", e + ", type: " + this.type);
}
}
The function digestJSON is called in 3 functions that employ anonymous callbacks: loadViaXHR2, loadViaXHR1 and loadViaJScript. The latter is the one that imports the JSON data via a Javascript file (see example below). When invoked, the 'callback' parameter would be set to 'digestJSON'.
function loadViaJScript(urlSpec, JSONobjName, callback, isAsync) {
console.log("Attempting to read JSON data using Javascript methods.");
var script = document.createElement('script');
var parent = document.getElementsByTagName('head').item(0) || document.documentElement;
script.type = "text/javascript";
script.onerror = function(e) {
alert("Error loading the '" + JSONobjName + "' file: '" + urlSpec + "'. Check that the file exists.");
console.error("Error loading via Javascript: ", e + ", type: " + this.type);
}
script.src = urlSpec;
parent.appendChild(script);
script.onload = function() {
callback(null, JSONobjName);
};
}
Sample data (trivial example): var JSONdata = '{"blue" : "is ok", "red" : "is my fave color"}';