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
Add a ment  | 

3 Answers 3

Reset to default 4

The 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