d3.js Using D3 with JSON and CSV One or two parameters in callback—error handling in d3.request()


Example

When using d3.request() or one of the convenience constructors (d3.json, d3.csv, d3.tsv, d3.html and d3.xml) there are many sources for error. There may be problems with the issued request or its response due to network errors, or the parsing might fail if the content is not well-formed.

Within the callbacks passed to any of the above mentioned methods it is, therefore, desirable to implement some error handling. For this purpose the callbacks may accept two arguments, the first being the error, if any, the second being the data. If any error occurred during loading or parsing information about the error will be passed as the first argument error with the data being null.

d3.json{"some_file.json", function(error, data) {
  if (error) throw error;   // Exceptions handling
  // Further processing if successful
});

You are, whatsoever, not obliged to provide two parameters. It is perfectly fine to use the request methods with a callback featuring only one parameter. To handle these kinds of callbacks there is a private function fixCallback() in request.js, which adjusts the way information is passed to the method's single argument.

function fixCallback(callback) {
  return function(error, xhr) {
    callback(error == null ? xhr : null);
  };
}

This will be invoked by D3 for all callbacks having only one parameter, which by definition is the data.

No matter how many parameters are supplied to the request method's callback, the rule for the data parameter is:

  • if the request fails, data will be null
  • if the request succeeds, data will contain the loaded (and parsed) contents

The only difference between the one-parameter vs. the two-parameter version is in the way information is provided about the error which may occur. If the error parameter is omitted, the method will fail silently leaving data as null. If, on the other hand, the callback is defined to have two arguments, information about an error during loading or parsing will be passed to the first parameter enable you to handle it appropriately.

The following four calls to d3.json demonstrate the scenarios possible for existing/non-existing files vs. one paramter/two parameter callbacks:

// FAIL: resource not available or content not parsable
// error contains information about the error
// data will be null because of the error
d3.json("non_existing_file.json", function(error, data) {
  console.log("Fail, 2 parameters: ", error, data);
});

// FAIL: resource not available or content not parsable
// no information about the error
// data will be null because of the error
d3.csv("non_existing_file.json", function(data) {
  console.log("Fail, 1 parameter: ", data);
});

// OK: resource loaded successfully
// error is null
// data contains the JSON loaded from the resource
d3.json("existing_file.json", function(error, data) {
  console.log("OK, 2 parameters: ", error, data);
});

// OK: resource loaded successfully
// no information about the error; this fails silently on error
// data contains the JSON loaded from the resource
d3.json("existing_file.json", function(data) {
  console.log("OK, 1 parameter: ", data);
});