goblin-esque
goblin-esque

Reputation: 465

d3.js/queue.js: How to skip errors in queue.js

I'm working with the last.fm API and queue.js to dynamically merge a user's Weekly Track List and Track Info datasets together. I'm running into a problem when my AJAX call for a certain song returns an error. My main question is, how do I skip these errors? Specifically, how do I alter Mike Bostock's taskThatSometimesFails function to continue onto the next d3.json call?

Here's my original code:

d3.json(top, function(json) {

    weeklyChart = json.weeklytrackchart.track;

    var q = queue()
        .defer(d3.json, top);

    weeklyChart.forEach(function(d) { 
            tracks = 'http://ws.audioscrobbler.com/2.0/?method=track.getInfo&api_key=...&artist='+ d.artist['#text'] + '&track=' + d.name + '&format=json';             
            q.defer(d3.json, tracks);
            });

    q.awaitAll(function(error) {    
            if (error) throw error;
            console.log(arguments);

Here's Mike Bostock's suggested way of skipping over error/null responses:

    queue(1)
        .defer(ignoreError, taskThatSometimesFails)
        .defer(ignoreError, taskThatSometimesFails)
        .awaitAll(function(error, results) {
          if (error) throw error; // never happens
          console.log(results); // e.g., [0.23068457026965916, undefined]
        });

    function ignoreError(task, callback) {
      task(function(error, result) {
        return callback(null, result); // ignore error
      });
    }

    function taskThatSometimesFails(callback) {
      setTimeout(function() {
        var x = Math.random();
        if (x > .5) return callback(new Error("failed"));
        callback(null, x);
      }, 250);
    }

I don't know node.js, and am pretty confused by how callback and setTimeout work. I tried adapting Mike's code to my situation, but I'm getting stuck on what to do with taskThatSometimesFails (where the magic is, I suppose). Here's my current, crappy adaptation:

d3.json(top, function(json) {

    weeklyChart = json.weeklytrackchart.track;

    var q = queue()
        .defer(d3.json, top);

    weeklyChart.forEach(function(d) { 
            tracks = 'http://ws.audioscrobbler.com/2.0/?method=track.getInfo&api_key=...&artist='+ d.artist['#text'] + '&track=' + d.name + '&format=json';             
            q.defer(d3.json, tracks);
            });

    function ignoreError(task, callback) {
        task(function(error, result) {
            return callback(null, result);
        });
    }

    function taskThatSometimesFails(callback) {
        setTimeout(function() {
            if (error) return callback(new Error("failed"));
            return callback(null, tracks); //or maybe return d3.json(tracks)?
        }, 1000);
    }


    q.awaitAll(function(error) {    
            if (error) throw error;

For now, any null responses are still breaking the whole queue. Any help, as always, appreciated. Thanks, guys.

Upvotes: 1

Views: 464

Answers (0)

Related Questions