0

and thank you in advance for any help. I am trying to build a web app that fetches data from an API, in this case a movie database API, but when i am trying to map all the movies from a specific title search i get the .map is not a function error, what i am doing wrong ? Can't i use useState to display the data ? When i do console.log (search) i can see the array with all the data :

import React, {useEffect, useState} from 'react';
import axios from 'axios';


export default function RandomFacts() {
  const [input, setInput] = useState('');
  const [search, setSearch] = useState(['']);

  useEffect(() => {
    apiCall();
  }, [input]);

  const moviesList = search && search.map((movie, index) =>
    <div className="movies" key="index">
      <li><h2>{movie.Title}</h2></li>
      <li><img src={movie.Poster} alt="poster" /></li>
    </div>,
  );

  const apiCall = async () => {
    const url = 'http://www.omdbapi.com/?s='+input+'&page=1&apikey=536a34c3';

    try {
      const response = await axios.get(url);
      if (response.status === 200 && response !== undefined) {
        const data = response.data;
        setSearch(data.Search);
        console.log(search);
      }
    } catch (error) {
      console.log(error);
    }
  };


  return (
    <div className="main">
      <h1>Movies</h1>
      <div className="textInput">
        <form>
          <label>
            <input type="text" value={input}
              onChange={(e) => setInput(e.target.value)}
            />
          </label>
        </form>
      </div>
      <div className="movies">
        {moviesList}
      </div>

    </div>

  );
}

enter image description here

kajó
  • 15
  • 1
  • 6
  • 1
    Can you share a console log of response? I’m assuming it’s an object with a data key that contains the array. So you’d need to change the setSearch to use res.data. – JBallin Nov 05 '20 at 16:44
  • Thanks for the help, edited the code, it had some errors, but the error it's still happening. Added the console.log – kajó Nov 05 '20 at 17:04
  • That's helpful! `data` was just a guess, I can see that you want `Search`. – JBallin Nov 05 '20 at 17:54
  • You need to see whats happening in the response, i recommend adding properties one by one to find the bug, whenever you get this error `.map is not a function error,` is because you are traying to use a array method in a non array value – aleEspinosaM Nov 05 '20 at 18:37

1 Answers1

1

The API is returning a response Object with a data key containing the keys Search, TotalResults, and Response. You're trying to map this response Object instead of the Array contained in response.data.Search.

So you should be using setSearch(response.data.Search).

JBallin
  • 8,481
  • 4
  • 46
  • 51
  • I used your idea and with a little fiddling i got it to work. Thank you very much. But i am struggling with another issue, the output does not match the input exactly, for example, if i search for Queen it only searches for Quee, only if write Queenn do i get the result for Queen, i believe it's some issue with useState when declaring const [input, setInput] = useState(""), but i have tried several things and i can't get it to work. – kajó Nov 05 '20 at 23:53
  • You're making the API call before the state had a chance to update `input`. There's no reason to store `input` in state in this case, why don't you just make the API call directly in the `onChange` instead of `setInput`? A better/advanced approach would be to use `useEffect` to make an API call whenever `state.input` changes. – JBallin Nov 06 '20 at 00:10
  • I am going the right way ? At least i tried it and it's updating input correctly, but i can't pass the if in useEffect, it's always returning undefined... – kajó Nov 06 '20 at 01:09
  • yea i think that should work. `status` isn't returned in the `response` object in this case (look at your console log). Try checking if `response && response.Response === 'True'` or you can try `response?.Response === 'True'` if your babel config supports `?`. Also you don't want to use `response.data` - we said `response.Search`. – JBallin Nov 06 '20 at 01:14
  • Tried both and still not getting pass the if. Used a couple console.log(input) just before the if, and everything runs great, the input variable is updated correctly. – kajó Nov 06 '20 at 01:30
  • Could be because of the async ? – kajó Nov 06 '20 at 01:31
  • Yea you're right about the async, good catch. Try something like [this](https://stackoverflow.com/a/56838577/4722345). – JBallin Nov 06 '20 at 02:02
  • Worked !! Changed the code in the original post for future reference in case someone gets in same trouble.Thank you very much for the help . It's for people like you that stackoverflow rules ! – kajó Nov 06 '20 at 09:46
  • Great! Given that I solved the original issue with the map not working, do you mind accepting + giving an upvote? – JBallin Nov 06 '20 at 18:46
  • Sorry, i thought i had done it before, but i haven't, did it now. Unfortunately it does not accept my upvote because i have less than 15 points reputation... :( – kajó Nov 06 '20 at 23:00