can't comment on the multiple .js files as I haven't yet refactored my app into multiple files.
As far as returning goes, you're working in an asynchronous application, so you can't. You have to use a callback, or a Spotify Promise might make your api more congruous with Spotify's. Look at the documentation for Promise.each().
Here is an implementation of the callback method. Changed a few things to make it easier for me to test. Made life a bit easier to pass the artist in instead. Also, there is no guarantee of the order they will come out since the second artist's toplist could come back faster than the first. You'll need to add more code if you want to keep order.
function doGetTopTrack(artist, num, callback) {
var artistTopList = Toplist.forArtist(artist);
artistTopList.tracks.snapshot(0,num).done(function (snapshot) { //only get the number of tracks we need
snapshot.loadAll('name').done(function (tracks) {
var i, num_toptracks;
num_toptracks = num; //this probably should be minimum of num and tracks.length
for (i = 0; i < num_toptracks; i++) {
callback(artist, tracks[i]);
}
});
});
};
function showRelated() {
var artist_properties = ['name', 'popularity', 'related', 'uri'];
models.Artist
.fromURI('spotify:artist:11FY888Qctoy6YueCpFkXT')
.load(artist_properties)
.done(function (artist) {
artist.related.snapshot().done(function (snapshot) {
snapshot.loadAll('name').done(function (artists) {
for (var i = 0; i < artists.length; i++) {
// am I missing something here?
doGetTopTrack(artists[i], 1, function (artist, toptrack) {
console.log("top track: " + toptrack.name);
var p = artist.popularity;
var n = artist.name;
var u = artist.uri;
//listItem = document.createElement("li");
console.log("<strong>Name</strong>: " + n.decodeForText() + " | <strong>Popularity: </strong> " + p + " | <strong>Top Track: </strong>" + toptrack.name);
//// undefined name
//$('#artistsContainer').append(listItem);
});
}
});
});
});
};
showRelated();