Reputation: 35
I am trying to delete an actor from actors array
which is inside movie object
.
Firstly, I map actors to display actors one by one and adding a remove action to button.
Whole ActorsList component
const PostList = ({ movie, removeActorFromMovie }, props) => {
return (
<div>
<h3>Actors in film </h3>
{movie.actors.map((actor, i) => (
<div key={actor}>
{actor}
<button onClick={() => removeActorFromMovie(actor)}>Usuń</button>
</div>
))}
</div>
);
};
const mapStateToProps = (state, props) => {
return {
movie: state.movies.find((movie) => movie.id === props.match.params.id),
};
};
const mapDispatchToProps = {
removeActorFromMovie,
};
export default withRouter(
connect
(mapStateToProps, mapDispatchToProps)(PostList)
);
Action:
export const removeActorFromMovie = (payload) => ({
type: "MOVIE_ACTOR_DELETE",
payload,
});
Reducer:
case "MOVIE_ACTOR_DELETE":
return [...state.filter((el) => el !== action.payload)];
Although, the payload wokrs great and returns the array item. It does not remove it from an array. My movies array with movie under index 0:
movies: Array(1)
0:
actors: (2) ['Robert XYZ', 'Jake XYZ']
director: "Quentino TARANTINO, TARANTINO"
id: "352cc51e-87c4-46ec-84a0-9f308ec1a71a"
productionYear: "123"
title: "Titanic"
and payload:
payload: "Robert XYZ"
type: "MOVIE_ACTOR_DELETE"
and as I said, this doest not remove the actor from actors array which is under index 0 in movies array
Upvotes: 0
Views: 82
Reputation: 5042
Update: I'm supposing your state is something like this:
state: {
movies: [...]
}
If you want to remove an actor from a movie you should also pass the payload a movie to remove the actor from.
removeActorFromMovie(actor, movie)
then in the reducer:
const { movie, actor } = action.payload;
const nextMovie = {
...movie,
actors: movie.actors.filter((a) => a !== actor)
};
const movieIndex = state.movies.findIndex((m) => m.id === movie.id);
return {
...state,
movies: [
...state.movies.slice(0, movieIndex),
nextMovie,
...state.movies.slice(movieIndex + 1)
]
};
OLD ANSWER (If you instead want to remove a movie):
If you want to remove a movie based on its actors you filter function will not work. You are trying to remove an item whose value is "Robert XYZ" but the element passed to you filter function is a movie.
if the state is like this:
movies: [
{
actors: ['Robert XYZ', 'Jake XYZ']
director: "Quentino TARANTINO, TARANTINO"
id: "352cc51e-87c4-46ec-84a0-9f308ec1a71a"
productionYear: "123"
title: "Titanic"
}
]
then you can do:
const nextItems = state.filter(movie => !movie.actors.includes(action.payload))
return nextItems;
There is no need to create a new copy of the filtered array with the spread operator because filter
return a new copy of the original array.
Upvotes: 1