How I Created A Personalised Discovery Playlist Using The Spotify API

In this post I'm going to walk through an example implementation of the Spotify API using Javascript. We will authorize a user, get that user's top tracks, then recommend some songs based on user favorites. The end result will have functionality similar to this:

Screenshot 2017-11-13 20.53.45.png

First, follow the instructions from Spotify to get a simple authorization application up and running using this tutorial. When you're finished and have the app running on localhost, feel free to dive into the next steps. 

All of the code here can be in index.html. The buttons should be in the HTML block and the rest can be added within the script tag. 

Buttons

First, let's add two buttons. One will start with a property of display:none, then be revealed later in the user flow. 

<div class="spotify-button" id="get-top-tracks">Get Top Tracks</div>
<div class="spotify-button recommendations" id="getrecommendations" style="display: none">Get Recommendations</div>

Event Listeners

Next, let's add an event listener to each of the buttons. One will run the function getTopTracks and the other will run the function getRecommendations. Both will pass through an access_token, which already accessible using the sample code. If you can't find the access_token, then you can also grab it off the page using getElementById. 

document.getElementById('get-top-tracks').addEventListener('click', function() {
  getTopTracks(access_token);                                       
});

document.getElementById('getrecommendations').addEventListener('click', function() {  
  getRecommendations(access_token)
});

Call the API

In order to retrieve the data, we'll call the Spotify API to retrieve our top tracks for the currently logged in user. Then we'll map over the JSON object that is returned, creating a checkbox input item for each song.

function getTopTracks(access_token) {
  $.ajax({
    url: 'https://api.spotify.com/v1/me/top/tracks?limit=10',
    headers: {
      'Authorization': 'Bearer ' + access_token
    },
    success: function(response) {
      $(".recommendations").show();
      mapOverSongs(response.items);
    }
  });
}

The response of this API call should contain an array of 10 songs. If you console.log(response.items) and don't get something like this, pause here to debug. 

Screenshot 2017-11-13 21.10.15.png

After receiving the response, we will first show the get recommendations button, enabling the second API call.

Then we will create a series of checkboxes. The checkbox input will contain a value of the song's ID, which is absolutely vital if we want to call the API later to retrieve more information based on these songs. 

Finally, we will use a simple innerHTML call to print the list of checkboxes out onto the screen. 

function mapOverSongs(songs) {
    $("#getrecommendations").show();
    songs.map( function(song) {
          var list = "<input type='checkbox' name='top-tracks' value='" +
                  song.id + "'>" +
                  "<a href='" + song.external_urls.spotify + "'>" +
                  song.name +
                  " by " + song.artists[0].name +
                  " from the album " + song.album.name +
                  "</a><br><br>";
          document.getElementById('top-tracks').innerHTML += list;
    });
}

The second API call is a little bit more tricky. First, we will loop over all the checkboxes to grab the data IDs of any that are selected. We'll concatenate those into a string, slice off the final comma, then append it to the API URL. 

The API call I leverage here is Get Recommendations Based on Seeds.

function getRecommendations(access_token) {
    var checkboxes = document.getElementsByName('top-tracks');
    var selected = "";
    for (var i=0, n=checkboxes.length; i<n; i++) {
        if (checkboxes[i].checked) {
            selected += checkboxes[i].value+",";
        }
    }
    selected = selected.slice(0, -1);
    $.ajax({
        url: 'https://api.spotify.com/v1/recommendations?market=US&seed_tracks=' + selected + '&limit=10',
        headers: {
        'Authorization': 'Bearer ' + access_token
        },
        success: function(response) {
            mapOverRecommendations(response.tracks);
        }
    });
}

Again, pause here if you don't receive an AJAX response that looks something like this, containing different songs from the first one. 

Screenshot 2017-11-13 21.21.25.png

We've now officially received our personalized playlist from Spotify! To cap things off, we'll just loop through each song and display it in a bootstrap table row so that the user can easily view their suggestions. 

function mapOverRecommendations(recommendations) {
  $(".recommendations-table").show();
  recommendations.map(function (song) {
    var list =
        "<tr><td><a target='_blank' href='" + song.external_urls.spotify + "'>" + song.name + "</a></td><td>" + song.artists[0].name + "</td><td>" + song.album.name + "</td></tr>";
    document.getElementById('recommendations').innerHTML += list;
  });
}

This will display the bottom table that was visible in the original example image, including a link to each song. Any questions or bugs? Let me know in the comments below! If not, enjoy coding and listening to your new personalized playlist!