interface Movie {
title: string;
year: string;
poster: string;
imdbID: string;
}
function TypescriptDemo() {
const [movie, setMovie] = React.useState<Movie | null>(null);
const [query, setQuery] = React.useState("");
const [error, setError] = React.useState("");
const defaultMovies = [
"tt1160419",
"tt4633694",
"tt2953050",
"tt5180504",
"tt0266543",
"tt8398600",
"tt0110357",
];
// get a number from 0 to final index of movies array
const randMov = Math.floor(Math.random() * defaultMovies.length);
React.useEffect(() => {
// fetch a random movie from the defaultMovies list
const fetchMovieById = async () => {
const res = await fetch(
`http://www.omdbapi.com/?i=${defaultMovies[randMov]}&apikey=${process.env.REACT_APP_OMDB_API_KEY}`
);
const data = await res.json();
setMovie({
title: data.Title,
year: data.Year,
poster: data.Poster,
imdbID: data.imdbID,
});
};
try {
fetchMovieById();
} catch (err) {
console.log(err);
}
}, []);
const handleSearch = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
setError("");
setMovie(null);
try {
const data = await searchMovie(query);
if (data.Response === "True") {
const firstResult = data.Search[0];
setMovie({
title: firstResult.Title,
year: firstResult.Year,
poster: firstResult.Poster,
imdbID: firstResult.imdbID,
});
} else {
setError(data.Error);
setMovie(null);
}
} catch (err) {
console.log(err);
}
};
const renderContent = () => {
if (error !== "")
return (
<ErrorCont>
<img src={NoDataImg} alt="" width="200px" />
<p>{error}</p>
</ErrorCont>
);
else if (movie === null)
return (
<>
<SkeletonCard />
<SkeletonInfo />
</>
);
else
return (
<a
href={`https://www.imdb.com/title/${movie.imdbID}/`}
target="_blank"
rel="noopener noreferrer"
>
<Poster src={movie.poster} />
</a>
<InfoBar>
<div>{movie.title}</div>
<YearWrapper>{movie.year}</YearWrapper>
</InfoBar>
);
};
return (
<>
{renderContent()}
<form action="" onSubmit={handleSearch}>
<SearchBar
value={query}
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
setQuery(event.currentTarget.value);
}}
placeholder="Search for a movie..."
/>
</form>
</>
);
}
const searchMovie = async (query: string) => {
// if query is empty, replace with a letter to give the
// 'too many results' error
const res = await fetch(
`http://www.omdbapi.com/?s=${query ? query : "s"}&apikey=${
process.env.REACT_APP_OMDB_API_KEY
}`
);
const data = await res.json();
return data;
};
Note: Code snippets do not include styling details unless they are the focus of the exercise.
Copyright © 2022 Explore React