Im writing a react application and while trying to get all warnings out I found a weird bug...
handleLike = id => {
const movies = [...this.state.movies];
const movie = movies.filter(obj => obj._id === id);
if (movie.map(obj => obj.liked) == "fa fa-heart-o") {
movie.map(obj => (obj.liked = "fa fa-heart"));
this.setState({ movies });
} else {
movie.map(obj => (obj.liked = "fa fa-heart-o"));
this.setState({ movies });
}
In if (movie.map(obj => obj.liked) == "fa fa-heart-o") I dont type check with (===) because it will be falsy for some reason, but obj.liked after Console Logging it with typeof, it says it is a String, so it definetly should be truthy, even after I added ToString() it did not get truthy... I double checked everything, am I missing something ?
Thanks in Advance!
You're doing a lot of unnessary map
ping.
1) movies.filter(obj => obj._id === id);
will return an array of one element which is a movie
object. To grab the actual movie object you need to use movies.filter(obj => obj._id === id)[0];
instead. You might also want to consider using find
(to grab the movie object) or findIndex
to identify the index of the movie you want.
2) if (movie.map(obj => obj.liked) == "fa fa-heart-o")
makes no sense - you're trying to compare an array (map
will always return a new array) to a string. I'm surprised that works at all.
Based on your comment I might rewrite your code as follows:
handleLike = id => {
const movies = [...this.state.movies];
// Find the index of the movie where `_id` matches `id`
const movie = movies.find(obj => obj._id === id);
// If the movie at the index is liked (either true/false),
// give the object a new property "icon" and give it a heart
if (movie.liked) {
movie.icon = "fa fa-heart";
} else {
// Otherwise give it an empty heart
movie.icon = "fa fa-heart-o";
}
// Set the new state (only once)
this.setState({ movies });
}