0

I am building a client-side application where I send requests to YouTube API, Instagram API, Tumblr API. When those requests are processed, an appropriate callback function is executed.

The problem is YouTube always finishes first, appends data to HTML via underscore.js templates. Then a few seconds later Instagram and Tumblr results are also appended.

My app.js file contains 3 separate plain javascript functions:

function showYoutube() { ... }
function showInstagram() { ... }
function showTumblr() { ... }

How could I display a simple "Loading..." message until all 3 callback functions have been successfully completed?

Update:

Still looking for a possible solution. Please note I do not have back-end service, thus I am limited to JSONP API requests only.

My API call is located in index.html and looks something like this:

<script 
    type="text/javascript" 
    src="http://gdata.youtube.com/feeds/users/GoogleDevelopers/uploads?v=2&alt=json-in-script&format=5&callback=showMyVideos">
</script>

So, function showMyVideos() has to be in the global scope. I've tried implementing jQuery Deffered and Async.js Parallel with no luck.

Sahat Yalkabov
  • 32,654
  • 43
  • 110
  • 175
  • What do your three functions return? – Beetroot-Beetroot Feb 25 '13 at 04:33
  • @Beetroot-Beetroot Nothing. They append
    elements to the DOM upon completion. My index.html contains underscore.js templates. The JSONP callback function takes that template, parses it and appends the div element (pinterest-style) into the main container.
    – Sahat Yalkabov Feb 25 '13 at 07:26
  • Then that's the first thing you need to address. In order to do something when all three functions are successfully complete, you need to return a Promise from each function, such that you have all three Promises in a common scope. If you could amend your question to include (simplified) code in at least one of the three functions, I'll see if I can show you how to make jQuery Deferreds/Promises work for you. – Beetroot-Beetroot Feb 25 '13 at 10:17
  • ... and when you've done that, remember to post a comment here (with @Beetroot-Beetroot in it) to alert me. – Beetroot-Beetroot Feb 25 '13 at 10:32

2 Answers2

1

Use a promise pattern, where you can fire a function/callback after n items have finished executed. Thus, you can display a spinner, fire your three async functions, and then upon completion of all three, fire a function to remove the spinner.

jQuery has promises and if you're using underscore, I think you can use underscore.deferred (I believe... I use jQuery)

1

You could also use the pretty brilliant async library that also works client side.

In this case it'd be best to use sync JSONP calls because well async will implement and control the async part for you as such.

//show loading icon
async.parallel([
    function (callback) {
        showYoutube() // have showYoutube() declared outside async.parallel 
                      // otherwise it will be inaccessible to the rest of your app.
        callback()
    },
    function (callback) {
        //send off to instagram
        callback()
    },
    function (callback) {
        //send off to tumblr
        callback()
    }
], function () {
    //all are done, hide loading icon
})
Niall Paterson
  • 3,580
  • 3
  • 29
  • 37
  • Uncaught ReferenceError: showYoutube is not defined. JSON-P callback cannot find the function, since it's inside async.parallel object. Am I doing something wrong? – Sahat Yalkabov Feb 24 '13 at 01:10
  • @TwilightPonyInc oooh I see now. So instead of jsonp-ing outside of async, jsonp inside of async if you can? that might make the callback function accessible. but it probably looks for it in the global scope yes... Hmm let me think for a sec its interesting. Implementing jsonp like this http://stackoverflow.com/questions/2681466/jsonp-with-jquery would work fine, because it would all be contained in the async -> parallel -> function. Is there something preventing you doing that? – Niall Paterson Feb 25 '13 at 15:42
  • That link you posted has a clever solution using `$.getJSON`. I will try that tonight and report back here. – Sahat Yalkabov Feb 25 '13 at 22:55
  • @TwilightPonyInc. yes there's a few different ways of doing it. Looking forward to it – Niall Paterson Feb 25 '13 at 23:17