调用Spotify API获取播放列表报错:无法读取name属性
问题排查与修复方案
核心问题分析
- 错误访问数组而非单个元素:你直接使用
items.name,但Spotify API返回的data.items是播放列表对象的数组,只有数组中的单个元素才包含name、id等属性,这是导致找不到name字段报错的直接原因。 - 异步执行未等待:
getPlaylists是异步函数,但你调用时未添加await,导致load函数提前返回空的playlists数组,同时异步操作的错误无法被捕获。 - 分页逻辑完全错误:
for (const i of total):total是数字(总播放列表数量),无法用for...of遍历,应遍历data.items数组。- 分页请求未使用API返回的
next地址,而是重复请求初始URL,永远无法获取后续页面的数据。
- 类型不匹配:你的
Playlist类型中songs字段定义为Track[],但Spotify API返回的tracks是包含href、total等属性的对象,并非直接的歌曲数组。
修复后的代码
export const load = async ({ fetch }) => { let playlists: Playlist[] = []; const ress = await fetch('api/token'); const access_token = await ress.text(); const getPlaylists = async (accessToken: string) => { let nextUrl = 'https://api.spotify.com/v1/me/playlists'; while (nextUrl) { const response = await fetch(nextUrl, { headers: { Authorization: `Bearer ${accessToken}` } }); if (!response.ok) { throw new Error(`Spotify API Error: ${response.statusText}`); } const data = await response.json(); // 遍历当前页的播放列表数组 for (const item of data.items) { playlists.push({ name: item.name, id: item.id, // 匹配API返回的tracks结构,若需具体歌曲需额外调用接口 songs: { total: item.tracks.total, href: item.tracks.href } }); } // 更新下一页请求地址 nextUrl = data.next; } }; // 等待所有异步操作完成后再返回结果 await getPlaylists(access_token); return { playlists }; }; // 修正后的类型定义 interface Playlist { name: string; id: string; songs: { total: number; href: string; // 若需存储具体歌曲,可后续扩展添加items: Track[] }; } interface Track { id: string; name: string; // 按需添加其他歌曲字段 }
关键修复说明
- 正确遍历播放列表:通过
for (const item of data.items)遍历数组中的单个播放列表对象,获取对应属性。 - 等待异步操作完成:调用
getPlaylists时添加await,确保所有播放列表数据加载完成后再返回结果。 - 实现正确分页:使用API返回的
data.next作为下一页的请求地址,直到next为null时终止循环。 - 匹配类型定义:调整
Playlist类型的songs字段结构,与Spotify API的响应格式保持一致,避免类型错误。
内容的提问来源于stack exchange,提问作者Benjamn
相关产品推荐
相关产品推荐

