Search code examples
javascriptjqueryjquery-uijquery-ui-autocompletespotify

jQuery Autocomplete Nested Ajax Calls


I am currently working on implementing an album search autocomplete using the Spotify Metadata API. I have most of the features complete, but I am having trouble when doing a nested call to retrieve the album cover art. Here I believe is the root of my problem. When I do the ajax call to retrieve the image it does work, and I get the right data, but the return statement is not getting executed. What I am trying to do is get the first four results, for each get an image and return the label, item and image.

 $('#spotify-album-search').autocomplete({
      source:
        function (query, process) {
          $.when(
            $.ajax({
                url: 'http://ws.spotify.com/search/1/album.json?q=' + query.term,
            })
          ).then(function (data) {
            process($.map(data.albums.slice(0, 4), function(item) {
              $.when (
                $.ajax({
                    url: 'https://embed.spotify.com/oembed/?url=' + item.href,
                    dataType: 'jsonp'
                })
              ).then(function (image) {
                // Input: The Rolling Stones
                console.log(item.artists[0].name + ' - ' + item.name + ': ' + image.thumbnail_url);
                // Console: The Rolling Stones - Let It Bleed: https://d3rt1990lpmkn.cloudfront.net/cover/91205a1c80960d7055f8ed1bbe022f195e1767a4
                return { label: item.artists[0].name + ' - ' + item.name, album: item, image: image.thumbnail_url };
              });
            }));
          });
      },
      select: function (e, ui) {
        console.log("selected= " + ui.item.album);
      },
      messages: {
        noResults: '',
        results: function() {}
      }
    })
    .data('ui-autocomplete')._renderItem = function(ul, item) {
      return $('<li></li>')
          .data( "ui-autocomplete-item", item)
          .append('<a>' + item.label + '<img src="' + item.image + '" alt="" />' + '</a>')
          .appendTo(ul);
    };

EDIT:

Here you can find a working fiddle, if you believe could help! http://jsfiddle.net/9GbkL/


Solution

  • Thanks to the help from Godsbest at the jQuery Forums, I was able to get this working. Paul was right, and I needed the function call instead of the return statement. If anyone ever runs into a problem like I did, here is a fiddle with Autocomplete working with Bootstrap 3 and the Spotify Metadata API:

    JS:

    $('#spotify-album-search').autocomplete({
          source:
            function (query, process) {
              $.when(
                $.ajax({
                    url: 'http://ws.spotify.com/search/1/album.json?q=' + query.term,
                })
              ).then(function (data) {
                var process_data = [];
                $.each(data.albums.slice(0, 4), function(i,item) {
                  $.when (
                   $.ajax({
                      url: 'https://embed.spotify.com/oembed/?url=' + item.href,
                      dataType: 'jsonp'
                   })
                  ).then(function (image) {
                    process_data.push( { artist: item.artists[0].name, album_name: item.name, label: item.artists[0].name + ' - ' + item.name, album: item, href: item.href, image: image.thumbnail_url.replace("cover", "60")} );
                    process( process_data );
                  });
                });
              });
          },
          open: function(event, ui) {
    
          },
          select: function (e, ui) {
            e.preventDefault();
            $('#spotify-id').val(ui.item.album.href);
            $(this).val(ui.item.label);
          },
          messages: {
            noResults: '',
            results: function() {}
          }
        })
        .data('ui-autocomplete')._renderItem = function(ul, item) {
          return $('<li>')
              .data( "ui-autocomplete-item", item)
              .append('<a>' + '<img width="50" src="' + item.image + '" alt="" />' + '<span class="ui-autocomplete-artist">' + item.artist  + '</span>' + '<span class="ui-autocomplete-divider"><i class="fa fa-minus"></i></span>' + '<span class="ui-autocomplete-album-name">' + item.album_name  + '</span>' + '<span class="ui-autocomplete-icon pull-right"><i class="fa fa-plus-circle fa-2x"></i></span>' + '</a>')
              .appendTo(ul);
        };
    

    http://jsfiddle.net/9GbkL/5/ . Happy coding!