You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何移除Spotify API返回items数组中的空对象行

Spotify API播放列表自动补全:移除空对象解决报错

问题背景

基于Spotify API实现播放列表自动补全功能,已成功建立连接并获取API响应,但返回的items数组中偶尔存在空对象,导致程序抛出**Cannot read properties of null (reading 'name')**错误。即使单独校验name属性,仍会出现images或owner相关的同类报错,需要在map处理结果前直接移除这些空对象。

已配置的权限范围:

$options = [
    'scope' => [
      'user-read-email',
      'user-read-private',
      'user-read-recently-played',
      'user-library-modify',
      'playlist-read-private',
      'playlist-read-collaborative',
      'playlist-modify-private',
      'playlist-modify-public',
      'user-follow-modify',
    ],
    'state' => $state,
];

前端实现脚本:

<script>
// Autocomplete for playlist lookup (step 1 of form)
$(function() {
  $("#playlist-link").autocomplete({
    source: function(request, response) {
      // Replace with your Spotify API access token
      const accessToken = "<?php echo $_SESSION['access_token'] ?>";

      $.ajax({
        url: "https://api.spotify.com/v1/search",
        headers: {
          "Authorization": "Bearer " + accessToken
        },
        data: {
          q: request.term,
          type: "playlist",
          limit: 10 // Adjust the number of results as needed
        },
        success: function(data) {
          // Can I delete the 'items' rows that are null here? If so, how??
          if (data.playlists && data.playlists.items) {
            const playlists = data.playlists.items.map(function(playlist) {
            return {
                label: playlist.name, // Displayed in the autocomplete list
                value: playlist.name, // Value inserted into the input field
                id: playlist.id, // Store the playlist ID for later use
                images: playlist.images, // store images for display
                owner: playlist.owner.display_name // store owner name
            };
            });
            response(playlists);
          } else {
            response([]); // Return an empty array if no results are found
          }
        },
        error: function(xhr, status, error) {
          console.error("Spotify API error:", error);
          response([]); // Handle errors gracefully
        }
      });
    },
    minLength: 3, // Start searching after 3 characters
    select: function(event, ui) {
      // Handle the selected playlist (e.g., store the ID)
      console.log("Selected playlist ID:", ui.item.id);
      // You can store the playlist ID in a hidden field or use it directly
      $("#playlist-id").val(ui.item.id); // Example: storing in a hidden input
    },
    open: function() {
      // Style the dropdown list (optional)
      $(".ui-autocomplete").css("z-index", 1000); // Ensure it's on top
    },
    focus: function(event, ui) {
      // Prevent the default behavior (inserting the value on focus)
      event.preventDefault();
    }
  }).autocomplete("instance")._renderItem = function(ul, item) {
    // Custom rendering of each item in the dropdown
    const image = item.images && item.images.length > 0 ? item.images[0].url : "placeholder.jpg"; // Use a placeholder if no image
    return $("<li>")
      .append(
        "<div>" +
        "<img src='" + image + "' style='width: 50px; height: 50px; margin-right: 10px; vertical-align: middle;'/>" +
        "<span style='vertical-align: middle;'>" + item.label + "</span>" +
          "<br> <span style='font-size: 12px; color: grey; vertical-align: middle;'>By: " + item.owner + "</span>" +
        "</div>"
      )
      .appendTo(ul);
  };
});

</script>

控制台报错截图:
Chrome控制台报错截图


解决方案

在map处理数组前,使用filter方法过滤掉空对象及缺少关键属性的项,同时给可选属性设置兜底值,彻底避免报错。

修改后的核心代码片段

success: function(data) {
  if (data.playlists && data.playlists.items) {
    // 过滤无效项:排除空对象,同时校验必须的name、id、owner属性
    const validPlaylists = data.playlists.items.filter(playlist => {
      return playlist && playlist.name && playlist.id && playlist.owner;
    });
    
    const playlists = validPlaylists.map(function(playlist) {
      return {
          label: playlist.name,
          value: playlist.name,
          id: playlist.id,
          images: playlist.images || [], // 兜底空数组,避免后续length访问报错
          owner: playlist.owner.display_name || 'Unknown' // 兜底默认名称
      };
    });
    response(playlists);
  } else {
    response([]);
  }
}

优化说明

  • 过滤逻辑:filter方法先排除null/undefined的项,再校验name、id、owner这些后续必须用到的属性,确保所有进入map的项都是有效的
  • 兜底处理:给images设置默认空数组,防止后续item.images.length报错;给owner.display_name设置Unknown默认值,避免用户未公开名称时显示异常

内容的提问来源于stack exchange,提问作者Antonio Romo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 00:03:14