2015-10-29 10 views
13

Ich benutze einen node.js Server, die Spotify API und das spotify-web-api-js Knotenmodul, um eine Webanwendung zu erstellen Benutzer können den Namen eines Künstlers eingeben, eine Liste von Liedern von verwandten Künstlern anzeigen und diese dann optional in ihrem eigenen Spotify-Konto speichern. Allerdings habe ich immer noch Probleme mit dem letzten Schritt.Wie wählt man einen Ereignis-Listener, der mich warten lässt, bis async.times fertig ist, um eine Funktion auszuführen

Mein Benutzerautorisierungsablauf geschieht zuerst:

if (params.access_token) { 

    s.setAccessToken(params.access_token); 

    s.getMe().then(function(data) { 

     console.log(data); 
     console.log(data.id); 
     user_id = data.id; 

Darunter ist, wo die die tatsächlichen Details der Songs von der API gesammelt werden. Obwohl es niedriger ist, tritt es zuerst auf und die Benutzerautorisierung erfolgt nur, wenn der Benutzer auf eine zweite Schaltfläche auf dieser Seite klickt.

async.times(counter, function(n, next){ 
     s.getArtistTopTracks(relatedArtists[n].id, "US", function (err, data2) { 
      relatedArtists[n].song = data2.tracks[0].name; 
      relatedArtists[n].uri = data2.tracks[0].uri; 
      console.log(relatedArtists[n].uri); 
      // make sure to put the access token here add song to playlist 
      // create array 
      song_uris.push(relatedArtists[n].uri); 
      console.log(song_uris); 

      // song_uris = relatedArtists[n].uri; 
      // 
      // console.log(song_uris); 

      next(null); 

     $("#playlist").load(function() { 
      s.addTracksToPlaylist(user_id, playlist_id, song_uris); 
      }); 
     }); 


     }, function(err) { 
     // console.table(relatedArtists); 

     for (k = 0; k < 20; k++) 
     { 
      $('#related-artist').append('<p><strong>' + relatedArtists[k].name + '</strong> -- \"' + relatedArtists[k].song + '\"</p>'); 


     } 

(JSBin of full code here, obwohl es vielleicht nicht arbeiten, weil ich meinen eigenen Server verwenden browserify auf)

Gerade jetzt, auf der Leitung 114 Ich habe song_uris.push(relatedArtists[n].uri); den Inhalt in ein Array schieben, mit async.times. Da dies unten ist, wo ich die Wiedergabeliste auf der Leitung 66 zu erstellen, zeigt es als leeres Array:

s.createPlaylist(user_id, {name: 'Related Artist Playlist'}).then(function(data3) { 
     console.log(data3); 
     playlist_id = data3.uri; 
     playlist_id = playlist_id.substring(33); 
     console.log(playlist_id); 


     console.log(song_uris); 


     }); 

Dort console.log(song_uris) zeigt ein leeres Array, so addTracksToPlaylist() bricht wie so:

enter image description here

Auf der anderen Seite, wenn ich versuche, addTracksToPlaylist() unten, habe ich keine Berechtigung, auf das Konto des Benutzers zuzugreifen.

Der Benutzerautorisierungsablauf wurde später hinzugefügt, nachdem die Grundfunktionalität zum Anzeigen einer Liste von Songs bereits funktioniert hat, aber ich bin mir nicht sicher, wie ich sie effektiv umformatiere, um diese Liste in der Wiedergabeliste meines Benutzers zu speichern. Momentan erstelle ich nur eine leere Playlist im Spotify-Account.

Welche Art von Ereignis Listener kann ich hinzufügen, so dass es warten wird, bis jede einzelne Instanz von async.times ausgeführt wird, so dass addTracksToPlaylist() funktionieren kann? Das DOM wird bereits initial geladen, bevor ich diese Daten bekomme. Ich schaute auf this question, aber es half mir nicht ganz, dieses Problem zu lösen. Vielen Dank!

EDIT: Ich habe jetzt die Array erstellt, wie ich es brauche, aber ich kann es immer noch nicht in die Playlist bekommen. Ich habe mit dem Ort meines Access-Tokens herumgespielt, damit ich auf die erstellte Playlist zugreifen kann, aber immer noch kein Glück.

Die console.log(song_uris); Anweisung in Zeile 130 zeigt die fertige Array, das ich brauche, aber wenn ich es in s.addTracksToPlaylist(user_id, playlist_id, song_uris); einfügen bekomme ich diese Fehler in der Entwicklerkonsole:

POST https://api.spotify.com/v1/users/tenderoni-/playlists/7MtQTzUsxD4IEJ8NmmE36q/tracks?uris= 400 (Bad Request) 
bundle.js:10616 
Uncaught (in promise) XMLHttpRequest {} 

Im Grunde ist es nicht die Parameter für einige Empfangs Grund. Und ich logge das playlist_id vorher, damit ich sagen kann, dass es funktioniert (auch sehe ich leere Wiedergabelisten mit dem angegebenen Titel, der in meinem Spotify Konto erstellt wird).

Voll aktualisierte Code hier: https://github.com/yamilethmedina/cs50xmiami/blob/master/assignments/portfolio/public/scripts.js

+0

Haben Sie vor, Anmeldeinformationen in den JSBin-Post aufzunehmen? Ich kann nicht sagen, ob diese von irgendeinem API-Dokument irgendwo sind oder wenn diese dir gehören. –

Antwort

2

Die Callback-Argument ASYNC.Zeiten können ein zweites "Ergebnis" -Argument bedeuten. Wenn Sie also "next" mit song_uri aufrufen, kommen Sie um jede Runde der Schleife herum. Sie können song_uris am Ende erhalten, einen Callback über searchArtists übergeben und dort verwenden. Skeleton-Version:

$(document).ready(function($) { 
    $('#s').on('submit', function() { 
     searchArtists($('#originalartist').val(), function(err, song_uris) { 
      if (params.access_token) { 
       // omitted 
       s.setAccessToken(params.access_token); 
       s.getMe().then(function(data) { 
        console.log(data); 
        console.log(song_uris); 
       }); 
      } 
     }); 
     return false; 
    }); 
}) 

function searchArtists(originalArtist, callback) { 
    s.getArtistRelatedArtists(originalArtistId, function(err, data) { 
     async.times(counter, function(n, next) { 
      // omitted 
      next(related_artists[n].uri) 
     }, function(err, song_uris) { 
      callback(err, song_uris); 
     }); 

    }); 

} 
+0

Würde 's.createPlaylist()' im ersten Teil innerhalb der 'getMe()' Funktion gehen? –

+0

Ja, da Sie immer noch die user_id vom getMe() - Callback benötigen, um s.createPlaylist() aufzurufen. Da sich getMe() bereits im Callback zu searchArtists befindet, können Sie auch auf die song_uris zugreifen. –

+0

Ich habe festgestellt, dass es von getArtistRelatedArtists() zu async.times() springt. sollte getArtistTopTracks() nicht zwischen diesen beiden Zeilen gehen? Ich erhalte das erste Lied von jedem der verwandten Künstler durch diese Funktion, um song_uris zu bevölkern. Ich denke, ich sollte zu meinem ursprünglichen Code zurückkehren und dann versuchen, dies erneut zu implementieren, weil ich denke, dass ich etwas anderes vermasselt habe, um die for-Schleife zu unterbrechen, die die Playlist auf dem Bildschirm ausgibt. Songs werden im Browser als nicht definiert angezeigt, aber nicht als Konsole , und während ich Zugriffe auf account.spotify.com sehe, erhalte ich keine Konsolenantwort mehr. –