dolki
dolki

Reputation: 93

Spotify implicit flow tutorial, token is null

New developer here trying to create a spotify search project to help me learn.

I'm following this tutorial so a user can log into my app using spotify. https://levelup.gitconnected.com/how-to-build-a-spotify-player-with-react-in-15-minutes-7e01991bc4b6

I am currently stuck at the section where it asks where you create the login button. I've followed the code examples, but when i load the page i get an error:

TypeError: Cannot read property 'token' of null
Landing.render
src/components/Landing.js:39
  36 | }
  37 | render() {
  38 |   return (
> 39 |     <div className="Landing">
     | ^  40 |       {!this.state.token && (
  41 |       <a
  42 |         className="btn btn--loginApp-link"

Here is what my code looks like

import './Landing.scss';
import React, { Component } from 'react';

export const authUrl = 'https://accounts.spotify.com/authorize';

const clientId = "MY_CLIENT_ID";
const redirectUri = "http://localhost:3000";
const scopes = [
  "user-read-currently-playing",
  "user-read-playback-state",
];

const hash = window.location.hash
  .substring(1)
  .split("&")
  .reduce(function (initial, item) {
    if (item) {
      var parts = item.split("=");
      initial[parts[0]] = decodeURIComponent(parts[1]);
    }
    return initial;
  }, {});
window.location.hash = "";

class Landing extends Component {
  componentDidMount() {
    let _token = hash.access_token;
    console.log(_token)
    if (_token) {
      this.setState({
        token: _token
      });
    } else {
      console.log("no token")
    }
  }
  render() {
    return (
      <div className="Landing">
        {!this.state.token && (
        <a
          className="btn btn--loginApp-link"
          href={`${authUrl}client_id=${clientId}&redirect_uri=${redirectUri}&scope=${scopes.join("%20")}&response_type=token&show_dialog=true`}
        >
          Login to Spotify
        </a>
      )}
      {this.state.token && (
        console.log("hello")
      )}
      </div>
    );
  }
}

export default Landing;

Can anyone push me in the right direction?

Upvotes: 4

Views: 193

Answers (1)

k.s.
k.s.

Reputation: 3004

The reason you are getting an error, is that the initial state values are not defined. So react sets this.state to null, thus you get the error.

How to solve the issue ?

  1. You set the default state in the constructor, this way this.state is not null
  constructor() {
    super();
    this.state = {
      token: ""
    };
  }
  1. you check if the state is not null (or just not a falsy value) and you render what you need
{this.state && !this.state.token && (...

And from the tutorial that you showed, you can see that the person actually declares a default state in the next code example

constructor() {
    super();
    this.state = {
      token: null,
    item: {
      album: {
        images: [{ url: "" }]
      },
      name: "",
      artists: [{ name: "" }],
      duration_ms:0,
    },
    is_playing: "Paused",
    progress_ms: 0
  };

Upvotes: 1

Related Questions