Add Genre and Movie Queries
Add Genre and Movie Queries
Expose the focused functions the home page needs. The important pattern is to make each function return application-shaped data rather than leaking raw TMDB response objects through the component tree.
Step 1 — Resolve featured genres
Add getGenreMap first. It asks TMDB for the complete movie genre list.
export async function getGenreMap(): Promise<Genre[]> {
const data = await tmdbFetch("/genre/movie/list");
return data.genres as Genre[];
}
Then add getFeaturedGenres. Use the readable FEATURED_GENRE_NAMES list and match those names against the response.
return FEATURED_GENRE_NAMES.map((name) => all.find((g) => g.name === name)).filter(
(g): g is Genre => Boolean(g)
);
This keeps the chip labels readable while still getting the current numeric ids from TMDB.
Step 2 — Build the summary transformer
Create toSummary so one place is responsible for converting the raw TMDB movie into the shape the cards use.
function toSummary(raw: any): MovieSummary {
return {
id: raw.id,
title: raw.title,
Continue the object with the year, poster URL, rounded rating, and genre ids. Keep the image URL construction here so components never need to know the TMDB image host.
Step 3 — Add discovery
Create discoverMovies with optional query, genreIds, sort, and page values. For the first version, use /search/movie when a query exists and /discover/movie otherwise.
if (query && query.trim().length > 0) {
data = await tmdbFetch("/search/movie", {
query: query.trim(),
page: String(page),
include_adult: "false",
});
}
For discovery, pass the mapped sort value, genres, page, and the vote-count threshold used by the finished project. Return only results and totalPages.
Checkpoint
The data layer can now resolve the featured genre chips and return a typed movie summary list from TMDB. The page is still using its local data until the final lesson in this module.