Reputation:
I am trying to get albums of a user with the following JavaScript function, first call gets album list, and while iterating in albums I get their cover picture:
function GetAlbums() {
FB.api('/me/albums', function(resp) {
var ul = document.getElementById('albums');
for (var i=0, l=resp.data.length; i<l; i++) {
var album = resp.data[i];
FB.api('/'+album.cover_photo, function(resp1) {
li = document.createElement('li'),
a = document.createElement('a');
a.innerHTML = "<img src='"+resp1.picture+"'/>"+album.name;
a.href = album.link;
li.appendChild(a);
ul.appendChild(li);
});
}
});
};
I don't know why but cover pictures are fetched ok, but album name is always same. Probably the inner FB.api call is async. and before it finishes the album iteration goes to the last element. How can I correct the code?
Upvotes: 0
Views: 604
Reputation: 7847
Your problem has to do with Javascript closures.
The innermost function gets triggered N times, but the invocations are executed after GetAlbums
has finished, and the album
variable equals the last album, in each of the N executions.
A quick fix would be to move FB.api('/'+album.cover_photo...
into a separate function:
function getAlbum(album) {
FB.api('/'+album.cover_photo, function(resp1) {
li = document.createElement('li'),
a = document.createElement('a');
a.innerHTML = "<img src='"+resp1.picture+"'/>"+album.name;
a.href = album.link;
li.appendChild(a);
ul.appendChild(li);
});
}
function GetAlbums() {
FB.api('/me/albums', function(resp) {
var ul = document.getElementById('albums');
for (var i=0, l=resp.data.length; i<l; i++) {
getAlbum(resp.data[i]);
}
});
};
The argument to getAlbum
is now available to the inner function, and doesn't change.
Upvotes: 1