user6488504
user6488504

Reputation:

react hooks cannot read property map of undefined

I am working on a movie list search app and then later might try to add lazy loading. This is just for POC purpose. Might add it to my portfolio later.

So, I have first created a global api.js where I will put the API calls with a callback and then call an API using callbacks from the components.

    const PageOneApi = (callback, errorCallback) => {
      axios("https://run.mocky.io/v3/36e4f9ce-2e48-4d44-9cf8-57f6900f8e12")
        .then((response) => {
          console.log("response from page one api", response);
          callback(response);
        })
        .catch((err) => {
          console.log("error from page one api", err);
          errorCallback(err);
        });
    };

export const movieListApi = {
  PageOneApi,
};

I have a movieList component:

function MovieList() {
  const [pageOneData, setPageOneData] = useState({});

  useEffect(async () => {
    await movieListApi.PageOneApi(
      (res) => {
        const pageOneData = res.data.page;
        setPageOneData(pageOneData);
        console.log("page one data: ", pageOneData);
      },
      (err) => {
        console.log(err);
      }
    );
  }, []);

  const movieList = pageOneData.contentItems;
  console.log(movieList);

  return (
    <div>
      <h4 className="text-white p-5">{pageOneData.title}</h4>
      <div className="grid grid-flow-row grid-cols-3 grid-rows-3 gap-7 m-5">
        {movieList.map((movie) => {
          console.log("movie", movie);
        })}
      </div>
    </div>
  );
}

Now, the problem is that I am unable to iterate through movieList, even though it's an array.

Upvotes: 0

Views: 133

Answers (2)

Priyank Kachhela
Priyank Kachhela

Reputation: 2635

Initially pageOneData is blank object so pageOneData.contentItems will return undefined so at first render react will throw error.

To solve this, you can use optional chaining so try something like below:-

{movieList?.map((movie) => {
          console.log("movie", movie);
        })}

Upvotes: 1

Shubham Khatri
Shubham Khatri

Reputation: 281734

Since pageOneData is initially an empty object, pageOneData.contentItems will be undefined in the first render cycle. causing movieList.map to fail as your useEffect call is made after the initial render and that fires an API which again is async and will take time to fetch the result

You can use default value for movieList to solve the error

const movieList = pageOneData.contentItems || [];

or

Optional chaining (?.)

 <div className="grid grid-flow-row grid-cols-3 grid-rows-3 gap-7 m-5">
    {movieList?.map((movie) => {
      console.log("movie", movie);
    })}
  </div>

Upvotes: 1

Related Questions