【问题标题】:How to handle response.item is undefined?如何处理 response.item 未定义?
【发布时间】:2020-06-15 17:08:40
【问题描述】:

虽然我绑定了 getNowPlaying,但我收到以下错误,如果我的代码中缺少某些内容,有人可以帮忙吗?我尝试导入 SpotifyWebApi 的方式是否错误?

这是导致问题的代码:

import React, { Component } from 'react';
import './App.css';

import SpotifyWebApi from 'spotify-web-api-js';
const spotifyApi = new SpotifyWebApi();

class App extends Component {
  constructor(props){
    super(props);
    const params = this.getHashParams();
    const token = params.access_token;
    if (token) {
      spotifyApi.setAccessToken(token);
    }
    this.state = {
      loggedIn: token ? true : false,
      nowPlaying: { name: 'Not Checked', albumArt: '' }
    }
    this.getNowPlaying=this.getNowPlaying.bind(this);
  }
  getNowPlaying(){
    spotifyApi.getMyCurrentPlaybackState()
      .then((response) => {
        this.setState({
          nowPlaying: { 
              name: response.item.name, 
              albumArt: response.item.album.images[0].url
            }
        });
      })
  }
  render() {
    return (
      <div className="App">
        <a href='http://localhost:8888' > Login to Spotify </a>
        <div>
          Now Playing: { this.state.nowPlaying.name }
        </div>
        </div>
    );
  }
}

export default App;

【问题讨论】:

  • 尝试console.log(response) 看看response 对象有哪些属性
  • 我在哪里添加它重要吗?当我在下面的getNowPlaying(){ console.log(response); spotifyApi.getMyCurrentPlaybackState.. 中添加它时,它说没有定义响应。
  • 是的,添加它的位置很重要,您应该在此行之前添加它this.setState({,因为getMyCurrentPlaybackState 是一个承诺,并且需要在您打印response 之前完成它控制台。
  • 响应 && response.item.album.images[0].url

标签: reactjs this bind spotify


【解决方案1】:

根据 Spotify 文档

响应 成功的请求将返回 200 OK 响应代码 一个 json 有效载荷,其中包含有关当前播放的信息 曲目或剧集及其上下文(见下文)。返回的信息 是最后一个已知状态,这意味着一个非活动设备可能是 如果是最后一个执行播放,则返回。

当没有找到可用设备时,请求将返回 200 OK 响应,但没有填充数据。

当当前没有曲目正在播放时,请求将返回 204 NO 没有负载的内容响应。

如果启用了私人会话,则响应将是 204 NO CONTENT 带有一个空的有效载荷。

也就是说,即使你的请求成功(200 OK),响应也可能是空的,所以你需要通过检查响应是否为空来进行防御性编程

我不确定请求返回的确切对象是什么,但你可以这样做

  spotifyApi.getMyCurrentPlaybackState()
  .then((response) => {
    this.setState({
      nowPlaying: { 
        name: response && response.item && response.item.name, 
        albumArt:  response && response.item && response.item.album && response.item.album.images.length > 0 && response.item.album.images[0].url
      }
    });
  })

这里的问题是你需要的属性嵌套很深,而且你需要检查图像数组长度是否大于0,所以可能更好的方法是将所有响应对象存储在状态中,然后检查它在渲染时。

如果这不可能,您可以使用可选链接,但为此您必须使用 babel 插件https://babeljs.io/docs/en/babel-plugin-proposal-optional-chaining

然后你就可以了

  spotifyApi.getMyCurrentPlaybackState()
  .then((response) => {
    this.setState({
      nowPlaying: { 
        name: response?.item?.name, 
        albumArt: response?.item?.album?.images[0].url
      }
    });
  })

【讨论】:

    猜你喜欢
    • 2021-06-03
    • 1970-01-01
    • 2018-05-23
    • 1970-01-01
    • 1970-01-01
    • 2018-06-07
    • 2010-12-31
    • 1970-01-01
    相关资源
    最近更新 更多