Javscript/JSON Spotify API Streaming Tracks

Hi,

I have a Spotify API request that searches for the album covers (and associated data) for my band. I have also filtered out elements from the array of objects that do not fit this criteria. I then have the images and data being displayed via a JS lightbox photo gallery. Having gotten this far I figured that I would add some audio on image click, which is working for the most part…The problem is that only the last streaming/snippet from the last object in the array is being played no matter which image I click on. Everything is being displayed through an unordered list in my index.html page.

Can anyone help? Thanks in advance to anyone who can help!

Here is my spotify.js code:

$(document).ready(function() {


var spotifyAPI = "https://api.spotify.com/v1/search";
var spotifyAlbumAPI = "https://api.spotify.com/v1/albums/";
var search = "Firebug";

//function to get individual album api:
function getAlbumInfo(callback) {

    $.getJSON(spotifyAPI, {
        q: search,
        type: "album",
      //  limit: 20
    }, function(data) {

         var array = [];


        $.each(data.albums.items, function(i, album) {
           console.log(data.albums.items);

        //    // filter out albums/collections from array that are not my band's songs &/or albums..get IDs from array/objects logged out to console
            if((album.id == "6HWxqdryeaBrcVNExMyzXC")||(album.id == "2NeiklEJ3gQE7bV9cp27hZ")||(album.id == "5sah14CPmQ1v2FUp2AKDql")||(album.id == "2GLF9bjkeGaKSiPAyLEWRb"))
         {

         }
         else
         {
          // push our albums to the array
          array.push(spotifyAlbumAPI + album.id);

        }

        });


        callback(array);


    });


}

        getAlbumInfo(function(result) {

           //get additional info from api to create photo list:
                function createAlbumList() {
                     var albumHTML = "";
                     $.each(result, function(i, album) {
                           $.getJSON(result[i], {
                           q: search,
                           type: "album",
                           limit: 12
                }, function(data) {
                  //  audioObject = new Audio(data.tracks.items[0].preview_url);

                  albumHTML += '<li data-name="' + data.artists[0].name + '">';
                  albumHTML += '<a href="' + data.images[0].url + '" data-lightbox="albums" data-title="';
                  albumHTML += 'Album Name: ' + data.name + '</br>';
                  albumHTML += 'Audio Tracks: ' + new Audio(data.tracks.items[0].preview_url) + '</br>';
                  albumHTML += 'Artist Name: ' + data.artists[0].name + '</br>';
                  albumHTML += 'Release Date: ' + data.release_date + '</br>';
                  albumHTML += 'SpotifyURL: ' + data.external_urls.spotify + '</br>';
                  albumHTML += '">';
                  albumHTML += '<img src="' + data.images[0].url + '"alt="' + data.name + '"></a></li>';

                   $('#albums').html(albumHTML);



                                     $('.musicButton1').click(function() {
                                        tinysort('ul#albums>li', { selector: 'img', attr: 'alt' });
                                     });

                                    $('.musicButton2').click(function() {
                                       tinysort('ul#albums>li', { selector: 'img', attr: 'photo_index' });
                                    });






              $('#albums > li > a').click(clickAlbum(data));

                                    //defined elsewhere for clarity
                                    function clickAlbum(data) {
                                      return function(e) {
                                         // this is the function the click event will use
                                         //data variable is captured here
                                         //
                                        e.preventDefault();




                                               var  playingCssClass = 'playing',
                                               audioObject = new Audio(data.tracks.items[0].preview_url);


                                                // stopMusic = $('#lightbox');

                                                 target = $(this);
                                                //


                                             //target.append(audioObject);
                                                 if (target.hasClass(playingCssClass)) {
                                                  audioObject.pause();
                                                  }
                                                  else {
                                                     audioObject.play();
                                                  }

                                                 $('#albums > li').removeClass(playingCssClass);

                                                // target.addClass(playingCssClass);

                                                 audioObject.addEventListener('ended', function () {
                                                 target.removeClass(playingCssClass);
                                                 });

                                                 audioObject.addEventListener('pause', function () {
                                                 target.removeClass(playingCssClass);
                                                });

                                      }
                          };//end function clickAlbum
            });//end getAlbumInfo
        });//end each
    }//end function(data)

    createAlbumList();
 });

 });// end document.ready.....

…and here is my project on gh-pages (Spotify API is in the middle of page…)

https://firebuggirl.github.io/api4/

Hey @firebuggirl,

Your main problem here is this line:

$('#albums > li > a').click(clickAlbum(data));

It’s being run for every album in the array, which means that for the last album it’s overriding everything, so clicking on any cover plays the same song.

You can fix it by doing something like this:

function createAlbumList() {
  $.each(result, function(i, album) {
    $.getJSON(album, {
        q: search,
        type: "album",
        limit: 12
      },
      function(data) {
        // Build a new string for each album
        var albumHTML = '';

        albumHTML += '<li data-name="' + data.artists[0].name + '">';
        // etc...

        // Wrap the string in a jQuery object, find the link element, and attach the click handler
        // with the current album data.
        var $albumHTML = $(albumHTML).find('a').click(clickAlbum(data));
        $('#albums').append($albumHTML);

        // ...
      });
  });
}

You could also move the sort button code outside of the loop too as they only need to be attached once, not for every album.

3 Likes

Hi @fretburner!

Thank you so much for sharing your knowledge of JS with me!

After a few hours of tinkering and refactoring/re-arranging my code to include all of the things that you have suggested, it’s working!!

Creating a new string inside of function(data), as opposed to how I had it placed before the JSON object made a huge difference, as did wrapping the string inside of an object.

You quite literally have made my week. Big learning experience for me!

Thanks so much for getting right to the point and for taking the time to explain what changes needed to be made.

Cheers:-)

PS. Here is what my code looks like now:

https://github.com/firebuggirl/api4/blob/master/js/spotify.js

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.