Search code examples
javascriptjquerypromisegetjson

Consolidated result object from a sequence of getJSON() calls


I'm using jquery after a long time. I've a requirement in which I need to call a few Rest APIs to fetch some data from each API. Then out of the result of all calls create a consolidated resultant object.

Something like this:

Output I'm looking for:

result {
    a: 123,
    b: 456, ....
    z: 789
}

Pseudo:

var result = {}; // final object containing consolidated result
$.getJSON(restapi1, function (data) {
    result["a"] = data.total;
});

// next rest call to fetch b
$.getJSON(restapi2, function (data) {
    result["b"] = data.total;
});

// so on...
// after fetching all values and storing them in one result object access elements like
var value1 = result.a;

I know I can use Promise.all(), but it gives an array as output & I want to avoid looping over it to fetch required element.

Please suggest. Thank You.


Solution

  • I know I can use Promise.all(), but it gives an array as output

    True, but you don't have to use the result it provides. You can use side-effects as you did in your pseudocode.

    If your various $.getJSON calls are all written individually, this is a use case for jQuery's $.when:

    var result = {}; // final object containing consolidated result
    $.when(
        $.getJSON(restapi1, function (data) {
            result["a"] = data.total;
        }),
        // next rest call to fetch b
        $.getJSON(restapi2, function (data) {
            result["b"] = data.total;
        }),
        // ...
    ).done(function() {
        // use `result`
    });
    

    If you have a loop instead, using $.when is possible but awkward:

    var result = {}; // final object containing consolidated result
    var promises = [];
    for (/*...*/) {
        promise.push($.getJSON(/*...*/));
    }
    $.when.apply($, promises).done(function() {
        // use `result`
    });
    

    ...so in that situation Promise.all is probably better provided you can assume it's present in the environment (natively, or because you polyfill it or use an enhanced promise lib):

    var result = {}; // final object containing consolidated result
    var promises = [];
    for (/*...*/) {
        promise.push($.getJSON(/*...*/));
    }
    Promise.all(promises).done(function() {
        // use `result`
    });