Skip to content
Advertisement

React.js TypeError: Cannot read property ‘map’ of null

I m not sure how can i explain it. But i will do my best. I’m developing a Movie App. I dont have problem about receiving data and viewing it on the screen. Besides i can see my errors on screen like “Too Many Results” but it’s working only on main page. When i’m doing my searching like only series. I have another page for it. I dont have problem about receiving data and viewing it on the screen. But i cant see my error codes.

Fetch Page

 import { useState, useEffect } from 'react';
const API_ENDPOINT = `https://www.omdbapi.com/?apikey=
${process.env.REACT_APP_MOVIE_API_KEY}`

 const useFetch = (urlParams) => {
    const [isLoading, setIsLoading] = useState(true);
    const [isError, setError] = useState({show:false, msg:''});
    const [data, setData] = useState(null);
    
    const fetchMovies = async (url) => {
      setIsLoading(true);
      try {
    const response = await fetch(url);
    const data = await response.json();
  if(data.Response === 'True' ){
    setData(data.Search || data);
    setError({show:false,msg: '' });
  }
  else if(data.Response=== null){
    setError({show:true,msg:data.Error})
  }
  else{
    setError({show:true,msg:data.Error})
  }
  setIsLoading(false);
      } catch (error) {
        console.log(error)
        setIsLoading(false);
      }
    };
  
  useEffect(() => {
    fetchMovies(`${API_ENDPOINT}&s=${urlParams}`) 
  },[urlParams])
    return {isLoading, isError, data }
}

export default useFetch;

Context page

import React, { useState, useContext} from 'react'
import useFetch from '../useFetch';

export const API_ENDPOINT = `https://www.omdbapi.com/?apikey=${process.env.REACT_APP_MOVIE_API_KEY}`

const AppContext = React.createContext()
const AppProvider = ({ children }) => {
  const [query, setQuery] = useState('spider-man');
  const [hero, setHero] = useState('batman');
  const [vero, setVero] = useState('high-score');
  const [games, setGames] = useState('game');
  const [dizi, setDizi] = useState('series');
  const {isLoading,isError,data:movies } = useFetch(`&s=${query}`);
  
  return <AppContext.Provider value={{isLoading,isError,movies,query,setQuery,dizi, setDizi,games, setGames, hero, setHero,vero, setVero}}>{children}</AppContext.Provider>
}

export const useGlobalContext = () => {
  return useContext(AppContext)
}

export { AppContext, AppProvider };

SearchFormType page

import React from 'react';
import { useGlobalContext } from '../context/context';


const SearchFormType = () => {
  const {vero, setVero,isError} = useGlobalContext();
  
  return (
  <form className="search-form" onSubmit={(e)=>
  e.preventDefault}>
    <h2>Search Series</h2>
    <input type="text " className="form-input" value={vero}
    onChange={(e)=> setVero(e.target.value)}/>
    {isError.show && <div className='error'>{isError.msg}</div>}
    </form>
  )
}

export default SearchFormType;

Series page

    import React from 'react'
import { useGlobalContext } from '../context/context';
import { Link } from 'react-router-dom';
import useFetch from '../useFetch';
const url =
  'https://upload.wikimedia.org/wikipedia/commons/f/fc/No_picture_available.png'

const Series = () => {
  const {vero,dizi} = useGlobalContext();
  
  const {isLoading,data:movies } = useFetch(`&s=${vero}&type=${dizi}`);
  
  if(isLoading){
    return <div className='loading'></div>
  }
 
return <section className="movies">
{movies.map((movie)=>{
  const {imdbID: key, Poster:poster, Title:title, Year:year} =
  movie
  return <Link to= {`/series/${key}`} key ={key} className="movie">
    <article>
      <img src={poster === 'N/A'? url : poster} alt={title} />
      <div className="movie-info">
        <h4 className="title">{title}</h4>
        <p>{year}</p>
      </div>
    </article>
  </Link>
  
})}</section>
}

export default Series;

I don’t know if it’s necessary but My home page

import React, { useContext }  from 'react'
import { useGlobalContext } from '../context/context'
import { Link } from 'react-router-dom'

const url =
  'https://upload.wikimedia.org/wikipedia/commons/f/fc/No_picture_available.png'

const Movies = () => {

  const { movies ,isLoading} = useGlobalContext();
  
  
  if(isLoading){
    return <div className='loading'></div>
  }
  

return <section className="movies">
 
{movies.map((movie)=>{
  const {imdbID: key, Poster:poster, Title:title, Year:year} =
  movie
  return (
    
  <Link to= {`/movies/${key}`} key ={key} className="movie">
    <article>
      <img src={poster === 'N/A'? url : poster} alt={title} />
      <div className="movie-info">
        <h4 className="title">{title}</h4>
        <p>{year}</p>
      </div>
    </article>
  </Link>
 
  )
 
})}</section>
}

export default Movies;

for last My main SearchForm

import React from 'react';
import { useGlobalContext } from '../context/context';

const SearchForm = () => {
  const {query, setQuery,isError} = useGlobalContext();
  
  return (
  <form className="search-form" onSubmit={(e)=>
  e.preventDefault}>
    <h2>Search Movies</h2>
    <input type="text " className="form-input" value={query}
    onChange={(e)=> setQuery(e.target.value)}/>
    {isError.show && <div className='error'>{isError.msg}</div>}
    </form>
  )
}

export default SearchForm

Advertisement

Answer

If you read the error message, it says you’re trying to call .map() on null value. In your code there’s two places where it could be:

movies.map((movie) => {
  ...
})

Even if you’re having trouble getting stack traces, you can figure out which spot is causing the error by logging the value of movies.

if (movies === null) {
  console.error('oh no, movies is null');
}

It’s possible that global context starts off with null movies or useFetch defaults to null movies while the request is pending.

User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement