miladmaaan
miladmaaan

Reputation: 57

How to use promises to return a collection built from a recursive AJAX call?

I am requesting data from the soundcloud API. It delivers the json result with 200 tracks per request, and a field called "next_href" which is basically the API call for the next 200 results (or however many remain). This is why I had to make a recursive function. Currently, I am able to get the full collection, and resolve the promise at the end of the recursion. However, I am unsure about how to return the collection to the main function. Before I restructured this function to use a promise, I was just calling addTracks in the final callback of the recursion, which worked, but I wanted to abstract the function so it's usable with any soundcloud API call.

Here is what I have so far:

function main(){
    // Use the user's soundcloud ID to request the their likes
    var url = "https://api-v2.soundcloud.com/users/" + userid + "/likes?offset=0&limit=200";

    var promise = getCollection(url);
    promise.then(function(collection){
    console.log("got here");
    //would like to have the collection to use here
    //addTracks(req, res, collection, 0);
    })  
}

function getCollection(url){
    var deferred = Q.defer();
    recurse(url, [], deferred);
    return deferred.promise;
}

function recurse(url, collection, promise){
    console.log(url);
    requestify.get(url).then(function(response){

        collection = collection.concat(response.getBody().collection);

        console.log(collection.length);

        if (response.getBody().next_href != null){
            var newurl = response.getBody().next_href;
            recurse(newurl, collection, promise);
        }
        else {
            promise.resolve();
        }

    })

}

Upvotes: 0

Views: 99

Answers (1)

SLaks
SLaks

Reputation: 887305

You don't need to use deferreds. Instead, just return the promise of the next step:

function main(){
    // Use the user's soundcloud ID to request the their likes
    var url = "https://api-v2.soundcloud.com/users/" + userid + "/likes?offset=0&limit=200";

    var promise = getCollection(url);
    promise.then(function(collection){
    console.log("got here");
        //would like to have the collection to use here
        addTracks(req, res, collection, 0);
    });  
}

function getCollection(url){
    return recurse(url, []);
}

function recurse(url, collection){
    console.log(url);
    return requestify.get(url).then(function(response){

        collection = collection.concat(response.getBody().collection);

        console.log(collection.length);

        if (response.getBody().next_href != null){
            var newurl = response.getBody().next_href;
            // Wait for the next call to complete and return its result.
            return recurse(newurl, collection);
        } else {
            // This is the final result of the promise
            return collection;
        }
    })

}

Upvotes: 1

Related Questions