React Jammming Project - Spotify API Request not working, undefined access token (Code 401)

Hey everyone,

I wanted to build the Jammming project with hooks for practice and I’m almost done. However, I can’t seem to get the GET request to work. Whenever I request data from the API, it returns a console error for a second and then the console resets.
The error is a GET error on line 37 in Spotify.js:
https://api.spotify.com/v1/search?type=track&q=$[object%200Object] 401

When I log the accessToken to the console, it just returns undefined. I double checked my client id and compared my code in the getAccessToken method with others in the forum, I can’t find the error.

I’d really appreciate a hint, I sadly didn’t manage to get it running in the past few days. If you need code from the other components I’ll gladly provide it.

Thanks :slight_smile:


Here is my current code:
Spotify.js

let accessToken;

const client_Id = "";

const redirectUri = "http://localhost:3000/";

const Spotify = {

  getAccessToken() {

    if (accessToken) {

      return accessToken;

    }

    // check for an accesToken match

    const accessTokenMatch = window.location.href.match(/access_Token=([^&]*)/);

    const expiresInMatch = window.location.href.match(/expires_in=([^&]*)/);

    // if token and expires exist in URL

    if (accessTokenMatch && expiresInMatch) {

      accessToken = accessTokenMatch[1];

      let expiresIn = Number(expiresInMatch[1]);

      window.setTimeout(() => (accessToken = ""), expiresIn * 1000);

      window.history.pushState("Access Token", null, "/");

      return accessToken;

    } else {

      const accessURL = `https://accounts.spotify.com/authorize?client_id=${client_Id}&response_type=token&scope=playlist-modify-public&redirect_uri=${redirectUri}`;

      window.location = accessURL;

      console.log(accessURL);

    }

  },

  // end getAccesToken

  // method which returns promise which will resolve to list of tracks from search

  search(searchTerm) {

    const accessToken = Spotify.getAccessToken();

    console.log(accessToken);

    const searchLink = `https://api.spotify.com/v1/search?type=track&q=${searchTerm}`;

    // line below is marked as error

    return fetch(searchLink, {

      headers: {

        Authorization: `Bearer ${accessToken}`

      }

    }

    ).then((response) => {

        return response.json(); //converts response to json

      }

    ).then((jsonResponse) => {

        if (!jsonResponse.tracks) { // if json does not contain any tracks, returns empty array

          return [];

        }

        return jsonResponse.tracks.items.map((track) => ({ //map converted json to an array of tracks

          id: track.id,

          name: track.name,

          artist: track.artists[0].name,

          album: track.album.name,

          uri: track.uri

        }));

      });

  },

  savePlaylist(playlistName, trackURIs) {

    if (!playlistName || !trackURIs) {

      return;

    }

    const accessToken = Spotify.getAccessToken();

    const headers = {

      Authorization: `Bearer ${accessToken}`,

      "Content-type": "application/json",

    };

    let userId;

    // fetch request which returns user's spotify user name

    return fetch("https://api.spotify.com/v1/me", { headers: headers }

    ).then((response) => response.json()

    ).then((jsonResponse) => {

        userId = jsonResponse.id;

        return fetch(`https://api.spotify.com/v1/users/${userId}/playlists`, {

          headers: headers,

          method: "POST",

          body: JSON.stringify({ name: playlistName }),

        })

          .then((response) => response.json())

          .then((jsonResponse) => {

            const playlistId = jsonResponse.id;

            return fetch(

              `https://api.spotify.com//v1/users/${userId}/playlists/${playlistId}/tracks`,

              {

                headers: headers,

                method: "POST",

                body: JSON.stringify({ uris: trackURIs })

              }

            );

          });

      });

  },

};

export default Spotify;

App.js

import React, { useState } from "react";
import Spotify from "../../util/Spotify";
import Playlist from "../Playlist/Playlist";
import SearchBar from "../SearchBar/SearchBar";
import SearchResults from "../SearchResults/SearchResults";
import "./App.css";

function App() {
  const [searchResults, setSearchResults] = useState([]);
  const [playlistTracks, setPlaylistTracks] = useState([]);
  const [playlistName, setPlaylistName] = useState("New Playlist");


  // add track to the playlist
  const addTrackHandler = (track) => {
    if (playlistTracks.find((foundTrack) => foundTrack.id === track.id)) {
      return;
    }
    setPlaylistTracks((prevTracks) => [...prevTracks, track]);
  };

  // remove track from the playlist
  const removeTrackHandler = (track) => {
    setPlaylistTracks((prevTracks) => [
      ...prevTracks.filter((filteredTrack) => filteredTrack.id !== track.id),
    ]);
  };

  // rename playlist
  const renamePlaylist = (name) => {
    setPlaylistName(name);
  };

  // save playlist and reset its name and tracks afterwards
  const savePlaylistHandler = () => {
    const trackURIs = playlistTracks.map((track) => track.uri);
    Spotify.savePlaylist(playlistName, trackURIs)
    .then(() => {
      setPlaylistName = "New Playlist";
      setPlaylistTracks = [];
    });
  };

  // search Spotify
  const searchHandler = (searchTerm) => {
    Spotify.search(searchTerm)
    .then((searchResults) => {
      // console.log(searchResults);
      setSearchResults(searchResults);
    });
  };

  return (
    <div className="App-body">
      <h1>
        Ja<span className="highlight">mmm</span>ing
      </h1>
      <div className="App">
        <SearchBar onSearch={searchHandler} />
        <div className="App-playlist">
          <SearchResults
            searchResults={searchResults}
            onAdd={addTrackHandler}
          />
          <Playlist
            playlistTracks={playlistTracks}
            playlistName={playlistName}
            onRemove={removeTrackHandler}
            renamePlaylist={renamePlaylist}
            onSave={savePlaylistHandler}
          />
        </div>
      </div>
    </div>
  );
}

export default App;


And SearchBar.js

import React from "react";
import "./SearchBar.css";
import { useState } from "react";

const SearchBar = (props) => {
  const [searchTerm, setSearchTerm] = useState("");

  const handleSearchTermChange = (event) => {
    setSearchTerm(event.target.value);
  };

  // calls searchHandler from App.js
  const searchHandler = (searchTerm) => {
    props.onSearch(searchTerm);
  };

  // triggers search by pressing Enter
  const handleKeyPress = (e) => {
    if (e.key === "Enter") {
      searchHandler();
    }
  };

  return (
    <div className="SearchBar">
      <input
        placeholder="What do you want to search for?"
        onChange={handleSearchTermChange}
        onKeyPress={handleKeyPress}
      />
      <button 
      className="SearchButton" 
      onClick={searchHandler}
      >
        SEARCH
      </button>
    </div>
  );
};

export default SearchBar;