Question

I am trying to create a helper file that will return the top track(s) of any artist's related artists. All I want to do use 1 artist URI to surface their related artists' name, popularity, and top track. And I want to separate out the top track functionality into a separate file that I can call whenever.

But, I can't seem to figure out how to properly return the top track of the related artists.

In my "get-toptrack.js" file:

   require([
      '$api/models',
      '$api/toplists#Toplist'
    ], function(models, Toplist) {
      'use strict';

      var doGetTopTrack = function(uri, num) {
        var artistURI = uri;
        var artist = models.Artist.fromURI(artistURI);
        var artistTopList = Toplist.forArtist(artist);

        artistTopList.tracks.snapshot().done(function(snapshot){

          snapshot.loadAll('name').done(function(tracks) {
            var i, num_toptracks;
            num_toptracks = num;

              for(i = 0; i < num_toptracks; i++){
                console.log("top track: " + tracks[i].name);
                // WHERE DO I RETURN THE TOP TRACKS??
              }
          });
        });
      };

      exports.doGetTopTrack = doGetTopTrack;
    });

In my "artist.js" file":

require([
    '$api/models',
    'scripts/get-toptrack'
  ], function(models, getTopTrack) {
    'use strict';

    var showRelated = function() {
      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++){
                var u, p, n, t, listItem;

                // store artist details
                p = artists[i].popularity;
                n = artists[i].name;
                u = artists[i].uri;

                // am I missing something here?
                t = getTopTrack.doGetTopTrack(u, 1);

                listItem = document.createElement("li");
                listItem.innerHTML = "<strong>Name</strong>: " + n.decodeForText() + " | <strong>Popularity: </strong> " + p + " | <strong>Top Track: </strong>" + t;

                // undefined name
                $('#artistsContainer').append(listItem);

              }
            });

          });
        });
    };

    exports.showArtists = showArtists;
  });

And in the 'main.js' file, I call the artists function to begin.

require([
  '$api/models',
  'scripts/artist'
], function(models, initArtist) {
  'use strict';

  initArtist.showRelated();
});
Was it helpful?

Solution

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();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top