简体   繁体   中英

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. Thanks in advanced. I appreciate your help!

 $('#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/

In asynchronous programming, return is only useful for forcing an exit. You can't actually return data....

The only way to use data in asynchronous programming is to send it to a function.

So, you need a function that can update the UI given the data...

Add this functionality where currently the console.log testing with the data is done.

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!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM