0

I am trying to make a url shortener using goog.gl api. Thanks to @Barmar now I can get my short URL using this code:

var shortURL;
    $.ajax({
        url: 'https://www.googleapis.com/urlshortener/v1/url?shortUrl=http://goo.gl/fbsS&key=AIzaSyANFw1rVq_vnIzT4vVOwIw3fF1qHXV7Mjw',
        type: 'POST',
        contentType: 'application/json; charset=utf-8',
        data: '{ longUrl: "' + longURL +'"}',
        dataType: 'json',
        success: function(response) {
            shortURL = response.id;
        }
    });

But I want to shorten an array of links! So I decided to use loop.

I created longURL[] and shortURL[] but if I run this code I get such output in shortURL array: [undefined × 10, "http://goo.gl/AxzWLx"]; Full code:

    var longURL = [];//there are some urls
var shortURL = [];
for (var k = 0; k < longURL.length; k++) {
    $.ajax({
        url: 'https://www.googleapis.com/urlshortener/v1/url?shortUrl=http://goo.gl/fbsS&key=AIzaSyANFw1rVq_vnIzT4vVOwIw3fF1qHXV7Mjw',
        type: 'POST',
        contentType: 'application/json; charset=utf-8',
        data: '{ longUrl: "' + longURL[k] +'"}',
        dataType: 'json',
        success: function(response) {
            shortURL[k] = response.id;
        }
    });
}
Vlad Holubiev
  • 4,876
  • 7
  • 44
  • 59

2 Answers2

2

This is a classic JavaScript problem. In your success function, you are using the same k for each AJAX call. You need to capture the value of k for each iteration.

var longURL = [];//there are some urls
var shortURL = [];
for (var k = 0; k < longURL.length; k++) {
    $.ajax({
        url: 'https://www.googleapis.com/urlshortener/v1/url?shortUrl=http://goo.gl/fbsS&key=AIzaSyANFw1rVq_vnIzT4vVOwIw3fF1qHXV7Mjw',
        type: 'POST',
        contentType: 'application/json; charset=utf-8',
        data: '{ longUrl: "' + longURL[k] +'"}',
        dataType: 'json',
        context: {key: k}, // the "this" value in the callback
        success: function(response) {
            shortURL[this.key] = response.id;
        }
    });
}
gen_Eric
  • 223,194
  • 41
  • 299
  • 337
2

The problem is that all your callback functions share the same value of k, because it's not a per-function closure variable. You can use the context: option to pass the appropriate value to each callback.

var longURL = [];//there are some urls
var shortURL = [];
for (var k = 0; k < longURL.length; k++) {
    $.ajax({
        url: 'https://www.googleapis.com/urlshortener/v1/url?shortUrl=http://goo.gl/fbsS&key=AIzaSyANFw1rVq_vnIzT4vVOwIw3fF1qHXV7Mjw',
        type: 'POST',
        contentType: 'application/json; charset=utf-8',
        data: '{ longUrl: "' + longURL[k] +'"}',
        dataType: 'json',
        context: k,
        success: function(response) {
            shortURL[this] = response.id;
        }
    });
}

Another solution is to use $.each(). Since each iteration is a function call, you'll close over the parameters:

var longURL = [];//there are some urls
var shortURL = [];
$.each(longURL, function(k, url) {
    $.ajax({
        url: 'https://www.googleapis.com/urlshortener/v1/url?shortUrl=http://goo.gl/fbsS&key=AIzaSyANFw1rVq_vnIzT4vVOwIw3fF1qHXV7Mjw',
        type: 'POST',
        contentType: 'application/json; charset=utf-8',
        data: '{ longUrl: "' + url +'"}',
        dataType: 'json',
        success: function(response) {
            shortURL[k] = response.id;
        }
    });
});
Barmar
  • 741,623
  • 53
  • 500
  • 612