const initialState = {
Most_Popular: [], // List Movies Popular Shown on home page
top_rated: [], // List top_rated Shown on home page
Movies: [], // All movies list
Movie: {}, // current Movie
isLoading: true, // cheak if page is loading
isError: false,
};
export const getMoviesGenres = createAsyncThunk(
"getMoviesGenres",
async (_, thunkAPI) => {
try {
const api = `api_key=${process.env.REACT_APP_KEY_API}`;
const data = await getJSON.get(`genre/movie/list?${api}`); // get all id genres
for (let i = 0; i <= data.data.genres.length; i++) {
if (!data.data.genres[i]) return; // guard clauses
const { id, name } = data.data.genres[i];
const dataMovieGenres = [
await getJSON.get(`discover/movie?${api}&with_genres=${id}`)
];
return dataMovieGenres;
}
} catch (error) {
return thunkAPI.rejectWithValue(error);
}
}
);
// get Movies Genres
builder
.addCase(getMoviesGenres.pending, (state) => {
state.isLoading = true;
state.isError = false;
})
.addCase(getMoviesGenres.fulfilled, (state, { payload }) => {
console.log(payload);
// state.Movies = payload.data.results;
state.isLoading = false;
state.isError = false;
})
.addCase(getMoviesGenres.rejected, (state, { payload }) => {
state.isLoading = false;
state.isError = false;
toast.error(payload.message);
});
Hi, I am trying to get all movies from all genres from tmdb api using redux tool kit.
I made a for loop that will make an api call until there are no more movies. After that I want to put all the movies into the Movies array.
I'm having a problem that I can't for some reason I only get genre 1 from the loop.
Again my goal is that dataMovieGenres Bring me all the movies you have and then I can handle my data in extraReducers Then of course iterate on them and display all the movies from all the categories I have.
like I mentioned I only get one genre.
I need some way to get any data from axios and transfer it to an array and then perform a return. The problem is that I don't want to use push because of a side effect.
Promises can only be fulfilled once. You are seeing the getMoviesGenres
resolve after the first "inner"/nested-loop request resolves, the rest are ignored since the action was already fulfilled.
You'll want to create an array of Promises for all genres' movies that can be awaited en masse.
Example:
export const getMoviesGenres = createAsyncThunk(
"getMoviesGenres",
async (_, thunkAPI) => {
try {
const api = `api_key=${process.env.REACT_APP_KEY_API}`;
const { data } = await getJSON.get(`genre/movie/list?${api}`);
const moviesReqs = data.genres.map(async ({ id }) => {
const { data } = getJSON.get(`discover/movie?${api}&with_genres=${id}`);
return data.results; // array of movies in genre
});
const movies = await Promise.all(moviesReqs)
.then(allMovies => allMovies.flat()); // flatten array of array of movies
return movies;
} catch (error) {
toast.error(error.message); // <-- toast from here, reducer is pure
return thunkAPI.rejectWithValue(error);
}
}
);
// get Movies Genres
builder
.addCase(getMoviesGenres.pending, (state) => {
state.isLoading = true;
state.isError = false;
})
.addCase(getMoviesGenres.fulfilled, (state, { payload }) => {
console.log(payload);
state.movies = payload; // <-- save payload into state
state.isLoading = false;
state.isError = false;
})
.addCase(getMoviesGenres.rejected, (state, { payload }) => {
state.isLoading = false;
state.isError = true;
});