4

This has me totally confused. I'm trying to run through a series of Youtube ids to check if the videos still exist.

I have all the ids in an array and want to check the gdata api to see if I get XML results or a Video not found 404 message.

I found a function on SO to check each id and add a row to a table.

var ytarray = ARRAY OF YOUTUBE IDs
var yttitles = ARRAY OF MATCHING TITLES FOR THE VIDS
var urlExists = function(url, callback){
$.ajax({
            type: 'HEAD',
            url: url,
            success: function() {
                callback(true);
            },
            error: function() {
                callback(false);
            }            
        });

    }
    var length = ytarray.length,
    for (var i = 0; i < length; i++) {
    urlExists('http://gdata.youtube.com/feeds/api/videos/'ytarray[i], function(success) {
        if (success) {
              $('#rows').append('<tr><td>'+yttitles[i]+'</td><td>'+ytarray[i]+'</td><td style="color: green">Found</td></tr>');
        } else {
              $('#rows').append('<tr><td>'+yttitles[i]+'</td><td>'+ytarray[i]+'</td><td style="color: red">Not Found</td></tr>');
        }
    });
    };
});
});

The table fills out but all of the rows contain the information for the last video not each one as it goes through the loop.

Testing with alerts it seems the table doesn't get filled out until all the for loops have completed.

I wonder if this is something to do with me not handling the asynchronous nature of AJAX correctly?

3 Answers 3

2
var ytarray   = ["ARRAY OF YOUTUBE IDs"],
    yttitles  = ["ARRAY OF MATCHING TITLES FOR THE VIDS"],
    urlExists = function(url){
        return $.ajax({
            type: 'HEAD',
            url : url
        });
    },
    output = function(state, i) {
        var tr  = $('<tr />'),
            td1 = $('<td />', {text : yttitles[i]}),
            td2 = $('<td />', {text : ytarray[i]}),
            td3 = $('<td />', {text : state ? 'Found' : 'Not found', 
                               style: state ? 'color: green' : 'color:red'});

        $('#rows').append( tr.append(td1, td2, td3) );
    },
    length = ytarray.length;

for (var i = 0; i < length; i++) {
    (function(k) {
        urlExists('http://gdata.youtube.com/feeds/api/videos/' + ytarray[k])
           .done(function() {
             output(true, k);
           }).fail(function() {
                output(false, k);
        });
    })(i);
}

Took some time to figure it out, but you'll need some closures, and a different way of handling the asynchronous behaviour.

Sign up to request clarification or add additional context in comments.

2 Comments

This works like a dream! I don't think I'd have worked this out for myself. Any explanation of what you did here would be really useful.
Just gave it a little structure, adding a clousure in the loop, and returned the deferred promise from the ajax function to work with it the way it was intended.
2

Try to preserve i. callbacks will be called after ajax response till then for loop is finished so value of i will be equal to length.

   for (var i = 0; i < length; i++) {
          (function(i){
            urlExists('http://gdata.youtube.com/feeds/api/videos/'ytarray[i], function(success) {
                if (success) {
                      $('#rows').append('<tr><td>'+yttitles[i]+'</td><td>'+ytarray[i]+'</td><td style="color: green">Found</td></tr>');
                } else {
                      $('#rows').append('<tr><td>'+yttitles[i]+'</td><td>'+ytarray[i]+'</td><td style="color: red">Not Found</td></tr>');
                }
            });
        })(i)
     }

2 Comments

I get "unexpected identifier". Does this refer to i?
@DaveR can't say, just put your code inside a anonymous function
2

I was puzzled by how to perform URL validation in a synchronous manner. I then happen to come across YQL, played with it for a while, and composed this:

  function isValidURL(url) {
    var encodedURL = encodeURIComponent(url);
    var isValid = false;

    $.ajax({
      url: "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D%22" + encodedURL + "%22&format=json",
      type: "get",
      async: false,
      dataType: "json",
      success: function(data) {
        isValid = data.query.results != null;
      },
      error: function(){
        isValid = false;
      }
    });

    return isValid;
  }

The usage is straight forward:

var isValid = isValidURL("http://www.wix.com");
alert(isValid ? "Valid URL!!!" : "Damn...");

Hope this can help whoever tried verifying a URL, synchronously.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.