admin管理员组文章数量:1402916
In React, I'm using Axios to map an array to output a list of movie names that are pulling from the MovieDB API. It connects to the MovieDB just fine, however, I get the following error in the console:
Uncaught TypeError: this.state.movies.map is not a function
I believe this is preventing the movie list from outputting to the browser.
Codesandbox link is here.
Here's the SearchBar ponent where the code lies:
import React, { Component } from "react";
import TextField from "@material-ui/core/TextField";
import axios from "axios";
import "../SearchBar/_search-bar.scss";
class SearchBar extends Component {
state = {
userSearchTerm: "",
movies: []
};
// When user types, match the value to state
onInputChange = e => {
this.setState({ userSearchTerm: e.target.value });
};
// On submitting the input, grab the API
onInputSubmit = e => {
e.preventDefault();
const movieName = this.state.userSearchTerm;
const KEY = "XXXXXXXXXX";
const searchQuery = `=${KEY}&language=en-US&query=${movieName}&page=10`;
axios.get(searchQuery).then(res => {
this.setState({ movies: res.data });
});
};
render() {
return (
<div>
<form onSubmit={this.onInputSubmit}>
<TextField
label="Search for a movie and hit enter..."
margin="normal"
className="search-bar"
onChange={this.onInputChange}
/>
</form>
<ul>
{this.state.movies.map(movie => (
<li key={movie.id}>{movie.results.title}</li>
))}
</ul>
</div>
);
}
}
export default SearchBar;
On a side note, I tested out this same code, but with a different API and it worked just fine. Is there something wrong with the API itself or the this.state.movies.map?
In React, I'm using Axios to map an array to output a list of movie names that are pulling from the MovieDB API. It connects to the MovieDB just fine, however, I get the following error in the console:
Uncaught TypeError: this.state.movies.map is not a function
I believe this is preventing the movie list from outputting to the browser.
Codesandbox link is here.
Here's the SearchBar ponent where the code lies:
import React, { Component } from "react";
import TextField from "@material-ui/core/TextField";
import axios from "axios";
import "../SearchBar/_search-bar.scss";
class SearchBar extends Component {
state = {
userSearchTerm: "",
movies: []
};
// When user types, match the value to state
onInputChange = e => {
this.setState({ userSearchTerm: e.target.value });
};
// On submitting the input, grab the API
onInputSubmit = e => {
e.preventDefault();
const movieName = this.state.userSearchTerm;
const KEY = "XXXXXXXXXX";
const searchQuery = `https://api.themoviedb/3/search/movie?api_key=${KEY}&language=en-US&query=${movieName}&page=10`;
axios.get(searchQuery).then(res => {
this.setState({ movies: res.data });
});
};
render() {
return (
<div>
<form onSubmit={this.onInputSubmit}>
<TextField
label="Search for a movie and hit enter..."
margin="normal"
className="search-bar"
onChange={this.onInputChange}
/>
</form>
<ul>
{this.state.movies.map(movie => (
<li key={movie.id}>{movie.results.title}</li>
))}
</ul>
</div>
);
}
}
export default SearchBar;
On a side note, I tested out this same code, but with a different API and it worked just fine. Is there something wrong with the API itself or the this.state.movies.map?
Share Improve this question edited Jul 9, 2019 at 13:22 Jack Bashford 44.2k11 gold badges55 silver badges82 bronze badges asked Jul 9, 2019 at 13:13 JD FillJD Fill 4122 gold badges8 silver badges26 bronze badges 4-
what does
res.data
look like? – Will Jenkins Commented Jul 9, 2019 at 13:16 - Did you mean to publish your API key to everyone? – spender Commented Jul 9, 2019 at 13:17
- When I add console logs to your get request to view what res is getting back it gets nothing. So you may want to look at your url and verify that it is correct first – Taylor Belk Commented Jul 9, 2019 at 13:22
- Object {data: Object, status: 200, statusText: "OK", headers: Object, config: Object…} data: Object page: 10 total_results: 47 total_pages: 3 results: Array[0] status: 200 statusText: "OK" headers: Object config: Object request: XMLHttpRequest – Taylor Belk Commented Jul 9, 2019 at 13:23
3 Answers
Reset to default 4The API you are using is returning an object with "results" being the key you are looking for. If you update your setState to this.setState({ movies: res.data.results });
you should get what you are looking for.
Axios Response Schema
As a side note I would guard your map function with something like {Array.isArray(this.state.movies) && this.state.movies.map(movie => (...
this will conditionally render the output only once movies
is set in state and is an array.
A working code:
import React, { Component } from "react";
import TextField from "@material-ui/core/TextField";
import axios from "axios";
import "../SearchBar/_search-bar.scss";
class SearchBar extends Component {
state = {
userSearchTerm: "",
movies: []
};
// When user types, match the value to state
onInputChange = e => {
this.setState({ userSearchTerm: e.target.value });
};
// On submitting the input, grab the API
onInputSubmit = e => {
e.preventDefault();
const movieName = this.state.userSearchTerm;
const KEY = "XXXXXX";
const searchQuery = 'https://api.themoviedb/3/search/movie?api_key=${KEY}&language=en-US&query=${movieName}&page=10';
axios.get(searchQuery).then(res => {
console.log("res is ------", res)
this.setState({ movies: res.data.results });
});
};
render() {
return (
<div>
<form onSubmit={this.onInputSubmit}>
<TextField
label="Search for a movie and hit enter..."
margin="normal"
className="search-bar"
onChange={this.onInputChange}
/>
</form>
<ul>
{this.state.movies.map(movie => (
<li key={movie.id}>{movie.original_title}</li>
))}
</ul>
</div>
);
}
}
export default SearchBar;
You should use this.setState({ movies: res.data.results });
and <li key={movie.id}>{movie.original_title}</li>
Let me know if it works.
You need to change the setState call to this:
this.setState({ movies: res.data.results });
The response is not an array, it is an object like this:
{
"page": 10,
"total_results": 136643,
"total_pages": 6833,
"results": [
{
"vote_count": 110,
"id": 13189,
"video": false,
"vote_average": 7.3,
"title": "A Christmas Carol",
"popularity": 6.52,
"poster_path": "/m3T3iLdE6J5PrqvvP0XNHBvM2bm.jpg",
"original_language": "en",
"original_title": "A Christmas Carol",
"genre_ids": [
18,
10751,
14,
10770
],
"backdrop_path": "/gaTpxTYQMGoagtMVYK8F7SjqTGM.jpg",
"adult": false,
"overview": "An old bitter miser who makes excuses for his uncaring nature learns real passion when three ghosts visit him on Christmas Eve.",
"release_date": "1984-12-17"
},
{
"vote_count": 419,
"id": 12103,
"video": false,
"vote_average": 6.1,
"title": "Don't Say a Word",
"popularity": 9.995,
"poster_path": "/qx3hgW9MqxsEEFjx4eSbpp1Fe2l.jpg",
"original_language": "en",
"original_title": "Don't Say a Word",
"genre_ids": [
53
],
"backdrop_path": "/AaOtoMzqWJPSNXPRKwbvqf6MbKo.jpg",
"adult": false,
"overview": "When the daughter of a psychiatrist is kidnapped, he's horrified to discover that the abductors' demand is that he break through to a post traumatic stress disorder suffering young woman who knows a secret..",
"release_date": "2001-09-28"
}
]
}
本文标签: javascriptUncaught TypeError thisstatemap is not a functionStack Overflow
版权声明:本文标题:javascript - Uncaught TypeError: this.state.map is not a function - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744380334a2603469.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论