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.