1
\$\begingroup\$

I am new to JavaScript, especially the wonders of async and closures and would like some help on the attached code. It is in a Chrome extension and retrieves a list of users albums with the Picasa Web API then gets the items in each album so I can filter out unwanted media and directories. It appears to be working as intended, but I am a little concerned that there are some unintended side effects lurking. I would also appreciate advice on how it may be improved.

// callback = function (albumList, error);
function loadAlbumList(callback) {
  var albumListQuery = '?v2&alt=json';
  var request = picasaPath + 'default/'  + albumListQuery;

  authenticatedXhr('GET',request, function (error, httpStatus, responseText) {
    var root = JSON.parse(responseText);
    var feed = root.feed;
    var entries = feed.entry || [], entry;
    var albumList = [], album;
    var ct = 0;

    for (var i = 0; i < entries.length; ++i) {
      (function(index) {
        entry = entries[index];
        loadAlbum(entries[index].gphoto$id.$t, false, function (photos) {
          if(!entries[index].gphoto$albumType && photos.length) {
            album = new Object();
            album.index = index;
            album.name = entries[index].title.$t;
            album.id = entries[index].gphoto$id.$t;
            album.ct = photo.length;
            album.thumb = entries[index].media$group.media$thumbnail[0].url;
            album.checked = false;
            album.photos = photos;
            albumList.push(album);
          }
          if(ct === (entries.length - 1)) {
            albumList.sort(function(a, b) {
              return a.index - b.index;
            });
            callback(albumList, error);
          }
          ct++;
       });
     })(i);
    }
  });
}

// callback = function (albumList, error);
function loadAlbum(id, preload, callback) {
  var request = picasaPath + 'default/albumid/' + id + '/' + photosQuery;

  authenticatedXhr('GET',request, function (error, httpStatus, responseText) {
    var root = JSON.parse(responseText);
    var feed = root.feed;
    var entries = feed.entry || [], entry;
    var imgs = [], img;
    var photos = [],photo;
    var url,author,width,height,aspectRatio;

    for (var i = 0; i < entries.length; i++) {
      entry = entries[i];
      if(isImage(entry)) {
        url = entry.media$group.media$content[0].url;
        width = entry.media$group.media$content[0].width;
        height = entry.media$group.media$content[0].height;
        aspectRatio = width / height;
        author = entry.media$group.media$credit[0].$t;

        if(preload) {
          img = new Image();
       // img.addEventListener('error', _imgError);
          img.src = url;
          imgs.push(img);
        }

        photo = new Object();
        photo.url = url;
        photo.author = author;
        photo.asp = aspectRatio.toPrecision(3);
        photos.push(photo);
      }
    }
    callback(photos, error);
  });
}

// callback = function (error, httpStatus, responseText);
function authenticatedXhr(method, url, callback) {
  var retry = true;
  (function getTokenAndXhr() {
    chrome.identity.getAuthToken({ 'interactive': true },
                                 function (access_token) {
      if (chrome.runtime.lastError) {
        callback(chrome.runtime.lastError);
        return;
      }

      var xhr = new XMLHttpRequest();
      xhr.open(method, url);
      xhr.setRequestHeader('Authorization',
                           'Bearer ' + access_token);
      xhr.send();
      xhr.onload = function () {
        if (this.status === 401 && retry) {
          // This status may indicate that the cached
          // access token was invalid. Retry once with
          // a fresh token.
          retry = false;
          chrome.identity.removeCachedAuthToken(
              { 'token': access_token },
              getTokenAndXhr);
          return;
        }

        callback(null, this.status, this.responseText);
      }
    });
  })();
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.