Jamming - Final Post Request Won't Work

Been stuck on this for hours would really appreciate any help as I’m almost there!

let accessToken;
const clientId = 'Correct Id goes here';
const redirectURL = 'http://localhost:3000/';

const Spotify = {
    getAccessToken() {
        if (accessToken) {
            return accessToken;
        };

        const newAccessToken = window.location.href.match(/access_token=([^&]*)/);
        const expirationTime = window.location.href.match(/expires_in=([^&]*)/);
       
        if (newAccessToken && expirationTime) {
            accessToken = newAccessToken[1];
            const expiresIn = Number(expirationTime[1]);
            window.setTimeout(() => accessToken = '', expirationTime * 1000);
            window.history.pushState('Access Token', null, '/');
            return accessToken;  
        } else {          window.location.replace(`https://accounts.spotify.com/authorizeclient_id=${clientId}&response_type=token&scope=playlist-modify-public&redirect_uri=${redirectURL}`);
        };
    },
        
    search(term) {
        //Spotify.getAccessToken() will RETURN accessToken from previous method.
        const accessToken = Spotify.getAccessToken();
        
        return fetch(`https://api.spotify.com/v1/search?type=track&q=${term}`, {
            headers: {
                Authorization: `Bearer ${accessToken}`,
                'Content-Type': 'application/json',
            }
        })
        .then(response => {
            if (response.ok) {
                return response.json();
            };
            throw new Error('Request failed!');
        }, networkError => {
            console.log(networkError.message);
        })
        .then(jsonResponse => {
            if (!jsonResponse.tracks) {
                return [];
            };
            return jsonResponse.tracks.items.map(track => ({
                    id: track.id, 
                    name: track.name,
                    artists: track.artists[0].name,
                    album: track.album.name,
                    uri: track.uri

            }));
        });
    },

    savePlaylist(playlistName, trackUri) {
       
        if (!playlistName || !trackUri) {
            return;
        };

        const accessToken = Spotify.getAccessToken(); //ISSUE IS HERE
        console.log(accessToken);
        const header = {Authorization: `Bearer ${accessToken}`};
        let userID;

      
       if (accessToken) {
            return fetch('https://api.spotify.com/v1/me', {headers: header})
            .then(response => {
                if (response.ok) {
                return response.json();
                };
            })
            .then(jsonResponse => {
                userID = jsonResponse.id;
                return fetch(`https://api.spotify.con/v1/users/${userID}/playlists`, {
                    headers: header,
                    method: 'POST',
                    body: JSON.stringify({name: playlistName}) //Body always contains data being sent to API. Needs to be stringified so it can be sent over server.
                })
                .then(response => {
                    if (response.ok) {
                        console("second fetch");
                        return response.json();
                    };
                    throw new Error('Request failed!');
                }, networkError => {
                    console.log(networkError.message);
                })
                .then(jsonResponse => {
                    let playlistID = jsonResponse.id;
                    console.log("uploaded");
                    return fetch(`https://api.spotify.com/v1/playlists/${playlistID}/tracks`, {
                        headers: header,
                        method: 'POST',
                        body: JSON.stringify({uris: trackUri})
                    });
                });
            })
        }
    }

    
};


export default Spotify;

I am trying to make a POST request to the Spotify API via the savePlayList method and keep getting an error 401. I realised this is because I have no access token, which is obtained using the getAccessToken() method. When this method is called in the search() method, I obtain an access token, but when I use the savePlayList() method it returns as undefined.

Any ideas what could be going on?

Edit: I think it’s because I’m clearing the URL using window.history.pushState() but I removed this and still get a fail to fetch.

Well can you track what’s going on when you invoke getAccessToken() the turn it fails?

You’d have to play around inserting a few statements to track your values inside but that’s the first place I’d look (since it’s running fine in your other calls and creates a bottleneck here).

So when I invoke getAccessToken() everything works but the accessToken value doesn’t seem to return. I’ve tried console.logging everything. If I remove the window.history.pushState part it yields the same accessToken as from when the search is committed but then the fetch() doesn’t go through.

Any ideas?

Thanks so much.

I would analyze the conditions that lead to no return:

  • !(newAccessToken && expirationTime)
  • !(accessToken)

Plus maybe throw a log to just confirm you’re hitting the else statement.

Then test if you’re getting both newAccessTokenand expirationTime.

If you’re not, that’s worth investigating as to why it is.

It’s just a matter of dwindling down possibilities, it helps to take notes with this on paper as well.

1 Like