DGB
DGB

Reputation: 1342

.map is not a function. map through an array of objects. (React Hooks)

I'm building a simple app that searches for movies from a movie DB. The search input successfully fetchs and sets the apiData to movies with the same value.

I'm struggling to map and display the title of the movies and get the error apiData.map is not a function

Data is state data is an array of objects.

I want to access the title from the objects i.e {title: 'mad max'} and display this.

Here's the code

const SearchPage = () => {
  const [apiData, setApiData] = useState({ results: {} });
  const [searched, setSearched] = useState([]);
  const [loading, setLoading] = useState(false);

  const handleSearch = (event) => {
    setSearched(event.target.value);
  };

  useEffect(() => {
    setLoading(true);
    fetchSearched(searched).then((data) => setApiData(data.results));
    setLoading(false);
  }, [searched]);

  return (
    <>
      <form className='search-form'>
        <input
          type='text'
          placeholder='search for a film'
          onChange={(event) => handleSearch(event)}
        />
      </form>
       // code below causes error when un-commented
      {/* <SearchList apiData={apiData} /> */}
    </>
  );
};
const SearchList = ({ apiData }) => {
  return (
    <div className='search-list'>
      SEARCH LIST
      <ul>
        {apiData.map((movie) => {
          return <SearchItem movie={movie} key={movie.id} />;
        })}
      </ul>
    </div>
const SearchItem = ({ movie }) => {
  return (
    <div className='search-item'>
      <li>{movie.title}</li>
    </div>

Mapping data from an API keeps tripping me up so any clarification would be appreciated.

Upvotes: 0

Views: 207

Answers (2)

san
san

Reputation: 1693

Because you set initial data of apiData is object. Please refer my code:

const SearchPage = () => {
  const [apiData, setApiData] = useState([]); // change to array
  const [searched, setSearched] = useState(""); // i think it is string
  const [loading, setLoading] = useState(false);

  const handleSearch = (event) => {
    setSearched(event.target.value);
  };

  useEffect(() => {
    if(!searched) return
    setLoading(true);
    fetchSearched(searched).then((data) => {
       setApiData(data.results)
       setLoading(false);
    });

  }, [searched]);

  return (
    <>
      <form className='search-form'>
        <input
          disabled={loading}
          type='text'
          placeholder='search for a film'
          onChange={(event) => handleSearch(event)}
        />
      </form>
       // code below causes error when un-commented
       <SearchList apiData={apiData} />
    </>
  );
};

const SearchList = ({ apiData = [] }) => {
  return (
    <div className='search-list'>
      SEARCH LIST
      <ul>
        {apiData.map((movie) => {
          return <SearchItem movie={movie} key={movie.id} />;
        })}
      </ul>
    </div>

Upvotes: 1

alaboudi
alaboudi

Reputation: 3423

your first line const [apiData, setApiData] = useState({ results: {} }); is setting an object to the state. Meanwhile, your api response is setting the an array to the state. I think you get an error due to how you are reading the initial state, and not due to the api call.

I think if you simply change this to const [apiData, setApiData] = useState([]); it will work. Happy coding

Upvotes: 0

Related Questions