4

Situation: User want to import Youtube playlist in a JQuery site using Youtube's JSON API.

Problem: Youtube only gives back first 50 entries, but playlists can be 100+ entries long (length is given by 'totalItems' in JSON response). All the entries need to be merged as 1 object and need to be pushed into an output function at the end.

Entry 1-50: http://gdata.youtube.com/feeds/api/playlists/84780DAC99E1A285?v=2&alt=jsonc&max-results=50&start-index=1

Entry 50-100: http://gdata.youtube.com/feeds/api/playlists/84780DAC99E1A285?v=2&alt=jsonc&max-results=50&start-index=50

Current code:

function fetchPlaylist(pid) {
    var the_url = 'http://gdata.youtube.com/feeds/api/playlists/' + encodeURIComponent(pid) + '?v=2&alt=jsonc&max-results=50';
    $.ajax({
        type: "GET",
        url: the_url,
        dataType: "jsonp",
        success: function (responseData, textStatus, XMLHttpRequest) {
            if (responseData.data != null) {
                if (responseData.data.items) {
                    outputFunction(responseData.data.items);
                } else {
                    console.log('No results for playlist: "' + pid + '"');
                }
            }
        }
    });
}

Question:

  1. What is the most efficient way to repeat the JSON calls until all the entries are received?

  2. How to combine the different responses into one object?

What I've tried:

Merging with the use of http://api.jquery.com/jQuery.extend/ , got stuck because of the complex/nested situation

MeProtozoan
  • 1,027
  • 3
  • 14
  • 26
  • 1
    For the merging, `$.extend()` has a deep copy option, for example: `$.extend(true, results, newResultsToAdd);` – Nick Craver Oct 04 '10 at 16:42

3 Answers3

4

Since you just want the items which is an array, you can use $.merge() in a repeating function:

function fetchPlaylist(pid, start, items) {
  items = items || [];
  start = start || 0;
  var the_url = 'http://gdata.youtube.com/feeds/api/playlists/' + encodeURIComponent(pid) + '?v=2&alt=jsonc&max-results=50';
  $.ajax({
      type: "GET",
      url: the_url,
      data: { start: start },
      dataType: "jsonp",
      success: function(responseData, textStatus, XMLHttpRequest) {
        if (responseData.data != null) {
          if (responseData.data.items) {
            $.merge(items, responseData.data.items); //add to items
            if (responseData.data.totalItems > start + 50) {
                fetchPlaylist(pid, start + 50, items);
            } else {
                outputFunction(items);
            }
          } else {
            console.log('No results for playlist: "' + pid + '"');
          }
        }
      }
  });
}

You can give it a try here, you just call it with the playlist id, like this:

fetchPlaylist("84780DAC99E1A285");​

Each time the request completes we see if the totalItems that youtube returns is higher than what we requested plus 50, if that's the case, fetch again, add those results...if not then we're done and pass the combined array to the outputFunction().

Nick Craver
  • 623,446
  • 136
  • 1,297
  • 1,155
1
  1. You should be able to use the start-index parameter to call the next set of results from google. You could probably call your fetchPlaylist() method recursively while changing the start-index for each call until you've gotten all of them.

  2. use .extend() to merge the results

fehays
  • 3,147
  • 1
  • 24
  • 43
0

I cannot post any comments yet because of my reputation. But shouldn't you make the increment of + 50 variable, using count(responseData.data.items), to cover for changes in the YouTube API?

I know the JSON request is called with max-results=50, but they could start limiting this to a lower number of items.

Wilgert
  • 706
  • 1
  • 6
  • 23