Reputation:
I have a beginner's problem. Maybe someone could help me. I am using an API of movies (TheMovieDb) and I try to convert the genres_ids to strings. The API returns ids for categories instead of labels, or names. So I have created a switch case in which each id corresponds to its category (ex: '28' corresponding to 'Action')but I can't use it in my component.
Here is my constructor:
constructor(props){
super(props);
this.state = {
films: [],
page: 1,
loading: false,
genre: null
};
}
Here is my function:
buildGenres(state, val) {
if (state === 'genre') {
val = convertGenres(val);
}
this.setState({ [state]: val });
}
Here is my Switch case:
module.exports = {
convertGenres: (genre) => {
switch (genre) {
case '12':
return'Adventure';
case '16':
return'Animation';
case '28':
return'Action';
case '35':
return'Comedy';
case '80':
return'Crime';
case '99':
return'Documentary';
case '18':
return'Drama';
case '10751':
return'Family';
case '14':
return'Fantasy';
case '36':
return'History';
case '27':
return'Horror';
case '10402':
return'Music';
case '9648':
return'Mystery';
case '10749':
return'Romance';
case '878':
return'Science Fiction';
case '10770':
return'TV Movie';
case '53':
return'Thriller';
case '10752':
return'War';
case '37':
return'Western';
default:
return genre;
}
}
};
And I try to use this in my component with a .map but I can get ids with only film.genre_ids in Tooltip title. how to do "if genre_ids = 28" then the genre is "Action":
const theMovies = this.state.films.map((film, index) => {
return(<Tooltip
TransitionComponent={Zoom}
id="Add to favorite"
title={<p>Category:{film.genre_ids}</p>}
placement={window.innerWidth > 959 ? "top" : "top"}
>
<AppsIcon className={classes.iconsHover} />
</Tooltip>)})
I'm really not sure I'm using the right method, so if you have a better idea, I'd be very grateful . Thanks in advance !
Upvotes: 0
Views: 1515
Reputation: 1038
A different approach will be to have an enum
type object already defined in code,
const stringIds = Object.freeze({ '12' :'Adventure', '16' : 'Animation', ...})
so you can directly access the string
ids, from the object as, stringIds['12'] = 'Adventure'
for you default case
you can check if the number string
id returns undefined
, if so just use the genre
as it is. You could also enclose this logic inside a function for ease of usage, like getConvertGenres
const getConvertGenres = (genre) => stringIds[genre] ? stringIds[genre] : genre
so you map
render
will be,
const theMovies = this.state.films.map((film, index) => {
return(<Tooltip
TransitionComponent={Zoom}
id="Add to favorite"
title={<p>Category:{getConvertGenres(film.genre_ids)}</p>}
placement={window.innerWidth > 959 ? "top" : "top"}
>
<AppsIcon className={classes.iconsHover} />
</Tooltip>)})
Edit for multiple id string
const getConvertGenresMulti = (genres) => {
const stringGenres = []
Object.keys(stringIds).forEach(id => {
if(genres.contains(id)){
stringGenres.push(getConvertGenres(id))
genres.replace(id,'')
}
})
return stringGenres.join(", ")
}
use this function instead of getConvertGenres
if you have multiple id string.
Upvotes: 0
Reputation: 1570
Your Genres will not be dynamic if you use switch case, if TheMovieDb change anything in there genres category then you might have to update your code and add a new case statement.
There is a separate API to get the genre https://api.themoviedb.org/3/genre/movie/list?api_key=<YOUR_API_KEY_HERE>&language=en-US
list which return an Array of Objects like this:
let genres = [{
"id": 28,
"name": "Action"
},
{
"id": 12,
"name": "Adventure"
}]
I have a working example of code which returns all the matching genres name according to genre_ids
class TheTmdbApp extends React.Component {
constructor(props) {
super(props)
this.state = {
movies : [ {
"popularity": 59.54,
"vote_count": 792,
"video": false,
"poster_path": "\/8j58iEBw9pOXFD2L0nt0ZXeHviB.jpg",
"id": 466272,
"adult": false,
"backdrop_path": "\/kKTPv9LKKs5L3oO1y5FNObxAPWI.jpg",
"original_language": "en",
"original_title": "Once Upon a Time in Hollywood",
"genre_ids": [28, 35, 80, 18, 37],
"title": "Once Upon a Time in Hollywood",
"vote_average": 7.6,
"overview": "A faded television actor and his stunt double strive to achieve fame and success in the film industry during the final years of Hollywood's Golden Age in 1969 Los Angeles.",
"release_date": "2019-07-26"
}, {
"popularity": 45.265,
"vote_count": 526,
"video": false,
"poster_path": "\/hgWAcic93phg4DOuQ8NrsgQWiqu.jpg",
"id": 452832,
"adult": false,
"backdrop_path": "\/oOROXoQ402tHgK6NowmMUSLffkW.jpg",
"original_language": "en",
"original_title": "Serenity",
"genre_ids": [9648, 53],
"title": "Serenity",
"vote_average": 5.2,
"overview": "Baker Dill is a fishing boat captain leading tours off a tranquil, tropical enclave called Plymouth Island. His quiet life is shattered, however, when his ex-wife Karen tracks him down with a desperate plea for help.",
"release_date": "2019-01-25"
}, {
"popularity": 50.454,
"vote_count": 113,
"video": false,
"poster_path": "\/vOl6shtL0wknjaIs6JdKCpcHvg8.jpg",
"id": 567609,
"adult": false,
"backdrop_path": "\/aNrNi5QExO6b8MnEGsfpgp21NIY.jpg",
"original_language": "en",
"original_title": "Ready or Not",
"genre_ids": [27, 9648, 53],
"title": "Ready or Not",
"vote_average": 7.5,
"overview": "A bride's wedding night takes a sinister turn when her eccentric new in-laws force her to take part in a terrifying game.",
"release_date": "2019-08-21"
}, {
"popularity": 46.348,
"vote_count": 2284,
"video": false,
"poster_path": "\/wgQ7APnFpf1TuviKHXeEe3KnsTV.jpg",
"id": 447404,
"adult": false,
"backdrop_path": "\/nDP33LmQwNsnPv29GQazz59HjJI.jpg",
"original_language": "en",
"original_title": "Pokémon Detective Pikachu",
"genre_ids": [28, 12, 14],
"title": "Pokémon Detective Pikachu",
"vote_average": 7,
"overview": "In a world where people collect pocket-size monsters (Pokémon) to do battle, a boy comes across an intelligent monster who seeks to be a detective.",
"release_date": "2019-05-10"
}, {
"popularity": 33.986,
"vote_count": 45,
"video": false,
"poster_path": "\/vVYU0x9FRpiJNX7c54ciFnRBVYG.jpg",
"id": 441282,
"adult": false,
"backdrop_path": "\/6rJAeP8xlq0bHUdCNg5epBvrFVa.jpg",
"original_language": "en",
"original_title": "Night Hunter",
"genre_ids": [80, 9648, 53],
"title": "Night Hunter",
"vote_average": 6.1,
"overview": "A police task force traps an online predator, only to discover that the depth of his crimes goes far beyond anything they had anticipated.",
"release_date": "2019-09-06"
}, {
"popularity": 48.493,
"vote_count": 1054,
"video": false,
"poster_path": "\/f4FF18ia7yTvHf2izNrHqBmgH8U.jpg",
"id": 504608,
"adult": false,
"backdrop_path": "\/oAr5bgf49vxga9etWoQpAeRMvhp.jpg",
"original_language": "en",
"original_title": "Rocketman",
"genre_ids": [18, 10402],
"title": "Rocketman",
"vote_average": 7.5,
"overview": "The story of Elton John's life, from his years as a prodigy at the Royal Academy of Music through his influential and enduring musical partnership with Bernie Taupin.",
"release_date": "2019-05-31"
}, {
"popularity": 46.85,
"vote_count": 3,
"video": false,
"poster_path": "\/eU0orGizEpOli4wtN8HtfOOJDlA.jpg",
"id": 516700,
"adult": false,
"backdrop_path": "\/nmHCKQ1GtlPLZVAtBfsYDqVPhPW.jpg",
"original_language": "id",
"original_title": "Gundala",
"genre_ids": [28, 80, 18],
"title": "Gundala",
"vote_average": 8.2,
"overview": "Sancaka has lived on the streets since his parents left him. Living a hard life, Sancaka survives by thinking about his own safety. When the condition of the city gets worse and injustice rages throughout the country, Sancaka must decide whether he continues to live to look after himself or rise to become their oppressed hero.",
"release_date": "2019-08-29"
}],
genres :
[
{
"id": 28,
"name": "Action"
},
{
"id": 12,
"name": "Adventure"
},
{
"id": 16,
"name": "Animation"
},
{
"id": 35,
"name": "Comedy"
},
{
"id": 80,
"name": "Crime"
},
{
"id": 99,
"name": "Documentary"
},
{
"id": 18,
"name": "Drama"
},
{
"id": 10751,
"name": "Family"
},
{
"id": 14,
"name": "Fantasy"
},
{
"id": 36,
"name": "History"
},
{
"id": 27,
"name": "Horror"
},
{
"id": 10402,
"name": "Music"
},
{
"id": 9648,
"name": "Mystery"
},
{
"id": 10749,
"name": "Romance"
},
{
"id": 878,
"name": "Science Fiction"
},
{
"id": 10770,
"name": "TV Movie"
},
{
"id": 53,
"name": "Thriller"
},
{
"id": 10752,
"name": "War"
},
{
"id": 37,
"name": "Western"
}
]
}
}
getMovieGenreName(genre_ids){
let genreIds = []
let genreNames = []
let genres = ""
this.state.genres.forEach((genre,index) => {
genreIds[index] = genre.id;
genreNames[index] = genre.name;
});
genre_ids.forEach((genre) => {
let genreIndex = genreIds.indexOf(genre);
let genreName = genreNames[genreIndex];
genres += genreName + ' . ';
})
genres = genres.slice(0, -2);
return genres
}
render() {
return (
<div>
{this.state.movies.map(movie => {
return (
<div>
<h4>{movie.title}</h4>
<span>Genres: {this.getMovieGenreName(movie.genre_ids)}</span>
</div>
)
})}
</div>
)
}
}
ReactDOM.render(<TheTmdbApp />, document.querySelector("#app"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<body>
<div id="app"></div>
</body>
Hope this helps, Happy Coding!!!
Upvotes: 2