JavaScript - Spotify API, выборка треков плейлистов - PullRequest
0 голосов
/ 03 мая 2018

Я использую API-интерфейс spotify для поиска плейлистов, а затем отображаю их в своем мобильном приложении. Я использую Ajax для получения информации из API, которая работает нормально, но я не могу заполнить div результатами и дать приложению возможность воспроизводить фрагменты музыки, поскольку оно не хочет разрешать событие слушатели. Вы не сможете увидеть все используемые переменные, но все до того, как этот код будет работать идеально.

var audioObject = null;
//Spotify page
$(document).on('pagecreate', '#spotify', function(){
console.log("Spotify");
$('#search').on('click', function() {
    //e.preventDefault();
    searchstring = cweather;

    if (!searchstring){
        console.log('no input');
        return;
    }
    console.log(searchstring);
    searchPlaylist(searchstring);
});

});

var userId;

var searchPlaylist = function () {
$.ajax({
    url: 'https://api.spotify.com/v1/search',
    headers: {
        Authorization: 'Bearer ' + spotifyAccessToken,
    },
    data: {
        q: searchstring,
        type: 'playlist',
        market: 'GB',
        offset: '0',
        limit: '5',
    },
    success: function (response) {
        console.log(response);

        var items = response.playlists.items;
        var resultsintohtml = '';

        $.each(items, function(index) {
            var id = items[index].id;
            var name = items[index].name;
            //var image = items[index].image[1].url;
            userId = items[index].owner.id;
            console.log(id, name, userId);
            resultsintohtml += '<div style="backgroundColor="red"" data-album-id="' + id + '" class="cover"></div>';
        });

        console.log(resultsintohtml);
        document.getElementById("results").innerHTML = resultsintohtml;

        addclickevents();
    }
});
};

var fetchTracks = function (playlistsId, userId, callback) {
$.ajax({
    url: 'https://api.spotify.com/v1/users/' + userId + '/playlists/' + playlistsId,
    headers: {
        Authorization: 'Bearer ' + spotifyAccessToken,
    },
    success: function (response) {
        console.log(response);
        callback(response);
    }
});
};

var addclickevents = function () {
$('.cover').click(function (e){
    console.log('get song');
    var target = $(this);

    if (target.hasClass('playing')) {
        audioObject.pause();
    } else {
        if (audioObject){
            audioObject.pause();
        }

        fetchTracks(target.data('playlist-id'), function (data) {
            audioObject = new
            Audio(data.tracks.items[0].preview_url);
            audioObject.play();
            target.addClass('playing');             
        });
        audioObject.addEventListener('pause', function(){
            target.removeClass('playing');
        });
    }
});
};

Поскольку этот код используется, я получаю следующие ошибки: Ошибка Я попытался переименовать переменные, но я получаю ту же ошибку. Я дважды проверил, есть ли какая-либо недостающая информация из спойти, но я уже использую все доступные идентификаторы. Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 03 мая 2018

Если audioObject присваивается только значение в обратном вызове fetchTracks, оно не будет определено при вызове audioObject.addEventListener.

Когда вы нажимаете .cover, вызывается прослушиватель событий. Если на обложке нет «игрового» класса, то:

  • audioObject по-прежнему равен нулю
  • fetchTracks будет вызван, но обратный вызов не сработает, пока не получен ответ
  • audioObject.addEventListener будет называться , но audioObject будет null
  • ответ на fetchTracks возвращается, и в обратном вызове вы устанавливаете audioObject как экземпляр Audio

Есть ли причина, по которой вы решили добавить прослушиватель событий вне обратного вызова?

0 голосов
/ 03 мая 2018

Обновление: Если присмотреться к вашему коду, я только что заметил, что fetchTracks ожидает 3 параметра, а вы передаете только 2. Второй параметр должен быть userId, а третий должен быть обратным вызовом. Я понятия не имею, что такое userId, но, предполагая, что это 123, вы должны запустить функцию следующим образом:

...
fetchTracks(target.data('playlist-id'), "123", function (data) {
  audioObject = new Audio(data.tracks.items[0].preview_url);
  audioObject.play();
  target.addClass('playing');             
  audioObject.addEventListener('pause', function(){
    target.removeClass('playing');
  });
});
...

Учитывая, что ваш код, скорее всего, вызывает неработающий URL с точки зрения Spotify (который должен отображаться как ошибка в вашей консоли - скорее всего, 404, но, возможно, также 403 или 422 ).


Первоначальный ответ:

Предполагая, что приведенный выше код является причиной ошибки, в строке 87 (в приведенном выше фрагменте) вы пытаетесь добавить прослушиватель событий для audioObject. Согласно ошибке, audioObject не является элементом DOM, но null. Поэтому вы можете проверить, поддерживает ли элемент метод, прежде чем применять его:

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

или ...

if (audioObject instanceof Element)
   audioObject.addEventListener('pause', function(){
     target.removeClass('playing');
   });

Примечание (в будущем): всякий раз, когда вы решите опубликовать изображения кода вместо самого кода в [SO], ожидайте, что вас проголосуют.

Еще одно примечание : вышеприведенное не исправляет логику вашего приложения, которая явно нарушена (или, по крайней мере, не работает должным образом). Он просто избегает выполнения кода при возникновении ошибки.


Возможно, вы хотите добавить прослушиватель событий внутри fetchTracks():

...
fetchTracks(target.data('playlist-id'), function (data) {
  audioObject = new Audio(data.tracks.items[0].preview_url);
  audioObject.play();
  target.addClass('playing');             
  audioObject.addEventListener('pause', function(){
    target.removeClass('playing');
  });
});
...

..., но без минимального рабочего примера я не могу быть уверен.

...