使用 Last.fm API 获取相似歌曲
Getting similar songs using Last.fm API
我正在尝试使用 Last.fm's API to find similar songs given a song name. Last.fm has a feature that can do this called track.getSimilar, but both "track" and "artist" are required parameters. However, because of the way this works, I can't figure out a way to either a) get both a song name, and the artist from one search bar input, or b) get the song's artist using track.search。这是我的代码中与此相关的部分:
const API_KEY = (my key);
const DEFAULT_TRACK = 'humble.'
const DEFAULT_ARTIST = 'kendrick lamar'
const RESULT_LIMIT = 5;
const RESULT_PAGE = 1;
const API_GET_SIMILAR_URL = `http://ws.audioscrobbler.com/2.0/?method=track.getSimilar&limit=${RESULT_LIMIT}&format=json&api_key=${API_KEY}`
const initialState = {
loading: false,
tracks: [],
errorMessage: null
}
const reducer = (state, action) => {
switch (action.type) {
case "SEARCH_REQUEST":
return {
...state,
loading: true,
errorMessage: null
};
case "SEARCH_SUCCESS":
return {
...state,
loading: false,
tracks: action.payload
};
case "SEARCH_FAILURE":
return {
...state,
loading: false,
errorMessage: action.error
};
default:
return state;
}
}
useEffect(() => {
fetch(`${API_GET_SIMILAR_URL}&page=${RESULT_PAGE}&artist=${DEFAULT_ARTIST}&track=${DEFAULT_TRACK}`)
.then(response => response.json())
.then(jsonResponse => {
const tracks = jsonResponse.similartracks[Object.keys(jsonResponse.similartracks)[0]];
dispatch({
type: "SEARCH_SUCCESS",
payload: tracks
});
});
}, []);
const search = (searchValue) => {
dispatch({
type: "SEARCH_REQUEST"
});
fetch(`${API_GET_SIMILAR_URL}&page=${RESULT_PAGE}&track=${searchValue}`)
.then(response => response.json())
.then(jsonResponse => {
if (!jsonResponse.error) {
const tracks = jsonResponse.similartracks[Object.keys(jsonResponse.similartracks)[0]];
dispatch({
type: "SEARCH_SUCCESS",
payload: tracks
});
} else {
dispatch({
type: "SEARCH_FAILURE",
error: jsonResponse.error
});
}
});
};
let {
tracks,
errorMessage,
loading
} = state;
console.log(state);
在我的搜索功能中,我在 Object.keys 行中收到 Uncaught (in promise) TypeError: Cannot convert undefined or null to object
错误,因为我在调用 API 时没有使用艺术家参数。我尝试使用 track.search 获取艺术家,但我不确定 where/how 是否将其合并到我的代码中。
感谢任何帮助或建议。谢谢。
我认为您的问题可能是缺少 URL 编码。我认为这是因为您的艺术家字符串中有一个 space,需要将其编码为 kendrick%20lamar
才能正确处理。
API's introduction page. UTF-8 is common, so you can use a function like encodeURI()
to achieve this (MDN Web Docs) 中提到了编码。
检验该理论的一种方法是使用 track.getSimilar docs 中的示例 URL 中的值,即艺术家 cher
和曲目 believe
。这些值方便地没有 spaces 或需要转义的特殊字符。通过了解预期的响应,它也是一个很好的功能基线,可以确保您的其余代码按预期运行。
也是一首好歌,一定要give it a listen:)
我正在尝试使用 Last.fm's API to find similar songs given a song name. Last.fm has a feature that can do this called track.getSimilar, but both "track" and "artist" are required parameters. However, because of the way this works, I can't figure out a way to either a) get both a song name, and the artist from one search bar input, or b) get the song's artist using track.search。这是我的代码中与此相关的部分:
const API_KEY = (my key);
const DEFAULT_TRACK = 'humble.'
const DEFAULT_ARTIST = 'kendrick lamar'
const RESULT_LIMIT = 5;
const RESULT_PAGE = 1;
const API_GET_SIMILAR_URL = `http://ws.audioscrobbler.com/2.0/?method=track.getSimilar&limit=${RESULT_LIMIT}&format=json&api_key=${API_KEY}`
const initialState = {
loading: false,
tracks: [],
errorMessage: null
}
const reducer = (state, action) => {
switch (action.type) {
case "SEARCH_REQUEST":
return {
...state,
loading: true,
errorMessage: null
};
case "SEARCH_SUCCESS":
return {
...state,
loading: false,
tracks: action.payload
};
case "SEARCH_FAILURE":
return {
...state,
loading: false,
errorMessage: action.error
};
default:
return state;
}
}
useEffect(() => {
fetch(`${API_GET_SIMILAR_URL}&page=${RESULT_PAGE}&artist=${DEFAULT_ARTIST}&track=${DEFAULT_TRACK}`)
.then(response => response.json())
.then(jsonResponse => {
const tracks = jsonResponse.similartracks[Object.keys(jsonResponse.similartracks)[0]];
dispatch({
type: "SEARCH_SUCCESS",
payload: tracks
});
});
}, []);
const search = (searchValue) => {
dispatch({
type: "SEARCH_REQUEST"
});
fetch(`${API_GET_SIMILAR_URL}&page=${RESULT_PAGE}&track=${searchValue}`)
.then(response => response.json())
.then(jsonResponse => {
if (!jsonResponse.error) {
const tracks = jsonResponse.similartracks[Object.keys(jsonResponse.similartracks)[0]];
dispatch({
type: "SEARCH_SUCCESS",
payload: tracks
});
} else {
dispatch({
type: "SEARCH_FAILURE",
error: jsonResponse.error
});
}
});
};
let {
tracks,
errorMessage,
loading
} = state;
console.log(state);
在我的搜索功能中,我在 Object.keys 行中收到 Uncaught (in promise) TypeError: Cannot convert undefined or null to object
错误,因为我在调用 API 时没有使用艺术家参数。我尝试使用 track.search 获取艺术家,但我不确定 where/how 是否将其合并到我的代码中。
感谢任何帮助或建议。谢谢。
我认为您的问题可能是缺少 URL 编码。我认为这是因为您的艺术家字符串中有一个 space,需要将其编码为 kendrick%20lamar
才能正确处理。
API's introduction page. UTF-8 is common, so you can use a function like encodeURI()
to achieve this (MDN Web Docs) 中提到了编码。
检验该理论的一种方法是使用 track.getSimilar docs 中的示例 URL 中的值,即艺术家 cher
和曲目 believe
。这些值方便地没有 spaces 或需要转义的特殊字符。通过了解预期的响应,它也是一个很好的功能基线,可以确保您的其余代码按预期运行。
也是一首好歌,一定要give it a listen:)