2

I have a search suggestion script that pulls results from two Google APIs, orders the results by an integer value and then displays it to a user. The script ensures it only returns the five most relevant responses for each query based on the rel attribute of each.

JSFiddle: http://jsfiddle.net/22LN5/

However, with this current set-up there is no fault tolerance; for example one API being on available or exceeding the query limit on one API so no results are returned.

How can this be resolved?

My jQuery code is:

var combined=[];
$(document).ready(function(){
    $("#search").keyup(function(e){
        $(this).html("");
        $.getJSON("http://suggestqueries.google.com/complete/search?q="+$("#search").val()+"&client=chrome&callback=?",function(data1){
            $.getJSON("https://www.googleapis.com/freebase/v1/search?query="+$("#search").val()+"&limit=3&encode=html&callback=?",function(data2){
                for(var key in data1[1]){
                    if(data1[4]["google:suggesttype"][key]=="NAVIGATION"){
                        combined.push("<li rel='"+data1[4]["google:suggestrelevance"][key]+"'><a href='"+data1[1][key]+"'>"+data1[2][key]+"</a></li>");
                    }else{
                        combined.push("<li rel='"+data1[4]["google:suggestrelevance"][key]+"'>"+data1[1][key]+"</li>");
                    }
                }
                for(var key in data2.result){
                    combined.push("<li rel='"+Math.round(data2.result[key].score*5)+"'> Freebase: "+data2.result[key].name+"</li>");
                }
                combined.sort(function(a,b){
                    return +$(b).attr("rel")-+$(a).attr("rel");
                });
                $("#suggest").html(combined.slice(0,5).join(""));
                combined=[];
            });
        });
    });
});
Callum Whyte
  • 2,379
  • 11
  • 36
  • 55
  • Does this help: http://stackoverflow.com/questions/6538470/jquery-deferred-waiting-for-multiple-ajax-requests-to-finish – 000 Jun 30 '13 at 01:11
  • @JoeFrambach Not as such. I need to separate my existing AJAX requests but ensure they are compiled and ordered at the same time. Any ideas? – Callum Whyte Jun 30 '13 at 01:13

1 Answers1

1

I've updated your fiddle: http://jsfiddle.net/22LN5/2/

I whipped up $.whenFaultTolerant, which will always return the promise in the event of completion or failure. Pass in a hash of deferreds, and out comes a hash of results! This is not a complete solution but I hope it is a good step in the right direction.

$.whenFaultTolerant = function(things) {
    var remaining = Object.keys(things).length;
    var outputs = {};
    var dfd = $.Deferred();
    $.each(things, function(key, thing) {
        thing.always(function(data) {
            outputs[key] = data;
            --remaining || dfd.resolve(outputs);
        });
    });
    return dfd.promise();
};

Usage:

    $.whenFaultTolerant({
        suggestqueries: $.getJSON("http://suggestqueries.google.com/complete/search?q="+$("#search").val()+"&client=chrome&callback=?"),
        googleapis: $.getJSON("https://www.googleapis.com/freebase/v1/search?query="+$("#search").val()+"&limit=3&encode=html&callback=?")
    }).done(function(data){
        console.log(data);
    });

Outputs:

{
    "suggestqueries": <the results from suggestqueries.google.com>,
    "googleapis": <the results from www.googleapis.com>
}
000
  • 26,951
  • 10
  • 71
  • 101