#javascript #arrays #reactjs #json #axios
Вопрос:
У меня есть приложение React, которое отправляет данные в мой пользовательский API-интерфейс Flask.
const params = {
id: this.props.user.uid,
title: movie.title,
movie_id: parseInt(movie.id, 10),
photo: "https://image.tmdb.org/t/p/w500/" movie.backdrop_path,
year: parseInt(movie.release_date.split("-")[0], 10),
rating: parseInt(parseFloat(movie.vote_average) * 10, 10),
overview: movie.overview,
genres: genres
};
Когда я распечатываю params.genres
его, на нем появляется что-то вроде этого ["Fantasy", "Comedy"]
.
Но когда я опубликую это:
axios.post("http://localhost:5000/user", params).then((data) => {
Полезная нагрузка составляет:
{"id":"id","title":"The Watch","movie_id":80035,"photo":"urltoimage","year":2012,"rating":55,"overview":"overview","genres":[]}
Все значения верны, за исключением жанров. И в моем бэкэнде написано то же самое. Что случилось?
Вся моя функция:
addMovie(movie) {
//get more data from tmdb
var genres = [];
axios
.get(
"https://api.themoviedb.org/3/movie/"
parseInt(movie.id, 10),
{
params: {
api_key: "dontsteelmytmdbkey;)",
},
}
)
.then((req) => {
for (let i = 0; i < req.data.genres.length; i ){
genres.push(req.data.genres[i].name);
}
});
console.log(genres);
const params = {
id: this.props.user.uid,
title: movie.title,
movie_id: parseInt(movie.id, 10),
photo: "https://image.tmdb.org/t/p/w500/" movie.backdrop_path,
year: parseInt(movie.release_date.split("-")[0], 10),
rating: parseInt(parseFloat(movie.vote_average) * 10, 10),
overview: movie.overview,
genres: genres
};
console.log(params.genres);
axios.post("http://localhost:5000/user", JSON.stringify(params)).then((data) => {
if (data.data.code === 112) {
// success alert
console.log("success alert");
// remove movie from list
let newMovies = this.state.movies;
for (let i = 0; i < newMovies.length; i ) {
if (newMovies[i].id === movie.id) {
newMovies.splice(i, 1);
}
}
this.setState({ movies: newMovies });
} else {
console.log("Backend error");
console.log(
"Error: " data.data.code " - " data.data.errno
);
this.setState({
showAlert: true,
alertSeverity: "error",
alertText: this.state.alertServerError,
});
}
});
// dont redirect
//this.props.history.push("/");
}
Комментарии:
1. Можете ли вы поделиться всем своим кодом, включая массив жанров, чтобы я мог взглянуть?
2. Я загрузил всю свою функцию добавления
3. Оба
console.log(genres)
иconsole.log(params.genres)
возвращают множество жанров, как я уже говорил ранее
Ответ №1:
Эти вызовы axios в данный момент оба асинхронны, и они не ждут, пока друг друга урегулируют. Попробуйте изменить свой код таким образом, чтобы дождаться разрешения первого вызова, а затем выполнить цикл по жанрам.
// add async to function definition
async function addMovie(movie) {
// get more data from tmdb
const genres = [];
try {
const response = await axios.get('https://api.themoviedb.org/3/movie/' parseInt(movie.id, 10), {
params: {
api_key: 'dontsteelmytmdbkey;)',
},
});
for (let i = 0; i < response.data.genres.length; i ) {
genres.push(response.data.genres[i].name);
}
} catch (error) {
console.error(error);
}
console.log(genres);
const params = {
id: this.props.user.uid,
title: movie.title,
movie_id: parseInt(movie.id, 10),
photo: 'https://image.tmdb.org/t/p/w500/' movie.backdrop_path,
year: parseInt(movie.release_date.split('-')[0], 10),
rating: parseInt(parseFloat(movie.vote_average) * 10, 10),
overview: movie.overview,
genres: genres,
};
console.log(params.genres);
axios.post('http://localhost:5000/user', JSON.stringify(params)).then((data) => {
if (data.data.code === 112) {
// success alert
console.log('success alert');
// remove movie from list
let newMovies = this.state.movies;
for (let i = 0; i < newMovies.length; i ) {
if (newMovies[i].id === movie.id) {
newMovies.splice(i, 1);
}
}
this.setState({ movies: newMovies });
} else {
console.log('Backend error');
console.log('Error: ' data.data.code ' - ' data.data.errno);
this.setState({
showAlert: true,
alertSeverity: 'error',
alertText: this.state.alertServerError,
});
}
});
// dont redirect
// this.props.history.push("/");
}
Комментарии:
1. Спасибо за заявление о попытке.
Ответ №2:
var genres = [];
const res = await axios
.get(
"https://api.themoviedb.org/3/movie/"
parseInt(movie.id, 10),
{
params: {
api_key: "dontsteelmytmdbkey;)",
},
}
)
for (let i = 0; i < res.data.genres.length; i ){
genres.push(res.data.genres[i].name);
}
Сделайте вашу функцию addMovie асинхронной, используйте ключевое слово async перед функцией addMovie.
зачем вам это нужно? потому что вам нужно подождать, пока ответ axios не разрешится.
для лучшего понимания вы можете прочитать больше об асинхронном ожидании
Ответ №3:
Он не ждет выполнения вызова API, который вы должны использовать асинхронно и ждать. Я добавил код ниже:
addMovie(movie) async {
//get more data from tmdb
var genres = [];
await axios
.get(
"https://api.themoviedb.org/3/movie/"
parseInt(movie.id, 10),
{
params: {
api_key: "dontsteelmytmdbkey;)",
},
}
)
.then((req) => {
for (let i = 0; i < req.data.genres.length; i ){
genres.push(req.data.genres[i].name);
}
});
console.log(genres);
const params = {
Комментарии:
1. Это неправильный способ дождаться разрешения запроса, асинхронность должна быть до того, как цепочка обратного вызова ключевого слова функции и ожидание не будут работать таким образом, я думаю, что этот ответ не должен быть помечен как принятый
2. у меня нет привилегий редактировать или комментировать ваш ответ, но ваш код в конечном итоге нарушит код, если запрос не будет обработан или из-за проблемы с сервером. вам нужно будет добавить вызов api в блок try catch.