0

I am having some difficulties with retrieving all data from youtube playlist. Here is my code:

function getApiUrl(nextPageToken) {
    return '<api_url>' + '&playlistId=' + '<playlistId>' + (nextPageToken !== null ? '&pageToken=' + nextPageToken : '');
}

function getPlaylist() {
    var titles = [],
        nextPageToken = null,
        url = getApiUrl(null);

    while(true) {
        // returns new Promise(...)
        doRequest(url).then(data => {
            // process data : push items to titles array
            nextPageToken = data.nextPageToken;
        });

        if (nextPageToken === undefined) {
            break;
        }

        url = getApiUrl(nextPageToken);
    }

    // returns empty array
    return titles;
}

Trying to break the loop inside the data handler leads to SyntaxError: Illegal break statement

bob_saginowski
  • 1,429
  • 2
  • 20
  • 35
  • Using an infinite loop that isn't related to a generator function typically isn't a good idea. What you should do here is set a variable to true, and when `nextPageToken === undefined`, set the variable to false. That will stop the loop – Sterling Archer Jun 11 '18 at 20:42
  • @SterlingArcher still does not solve the problem with the empty array – bob_saginowski Jun 11 '18 at 20:52
  • @SterlingArcher wouldn't that not work since the assignment to nextPageToken is asynchronous? – dgeare Jun 11 '18 at 20:52
  • You have to roll all the code up into the `then` for it to work correctly. Busy waiting around a promise is probably doing more harm than good. – ChiefTwoPencils Jun 11 '18 at 21:16

2 Answers2

2

The problem you are having is that the loop is synchronous but the assignment of nextPageToken is asynchronous. I'm actually not sure, but would something like this work using recursion

function getList(url){
    return doRequest(url).then(data => {
        if(data.nextPageToken !== undefined){
            //titles.push()... whatever you're putting into titles
            var nextUrl = getApiUrl(data.nextPageToken);
            return getList(nextUrl);
        }else{
            return;
        }
    });
}
dgeare
  • 2,618
  • 5
  • 18
  • 28
1

I think you can use await operator.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await

function getApiUrl(nextPageToken) {
    return '<api_url>' + '&playlistId=' + '<playlistId>' + (nextPageToken ? '&pageToken=' + nextPageToken : '');
}

async function getPlaylist() {
    var titles = [],
    nextPageToken = null,
    url = getApiUrl(null);


    // returns new Promise(...)
    nextPageToken = await doRequest(url).nextPageToken;

    url = getApiUrl(nextPageToken);

    // returns empty array
    return titles;
}
lmarqs
  • 1,469
  • 13
  • 16