Skip to content

How do I combine two fetch requests to get the information I need?

I am writing a site with information about films. I need to get my hands on genres. But the problem is this. In the request, where all the main information is located, the genres are indicated by id. I need to make another request where there are these id and genre names. In a Vue component, I made a for loop. With it, I show basic information besides genres. How can I combine the two queries?

My Code:

movies.js

export default {
  actions: {
    async getPopularFilms({ commit }) {
      const res_movies = await fetch(
        'https://api.themoviedb.org/3/movie/popular?api_key=d502a3d84eb533756ec099ef127a2acd&language=en-US&page=1'
      );
      const { results } = await res_movies.json();
      commit('updateFilms', results);

      // Fetch genres
      const res_genres = await fetch(
        'https://api.themoviedb.org/3/genre/movie/list?api_key=d502a3d84eb533756ec099ef127a2acd&language=en-US'
      );
      const { genres } = await res_genres.json();

      let ids = [];
      let genres_ids = [];
      for (let id = 0; id < results.length; id++) {
        ids.push(results[id].genre_ids);
      }
      for (let id = 0; id < genres.length; id++) {
        genres_ids.push(genres[id]);
      }
      console.log(ids);
      console.log(genres_ids);
    },
  },
  mutations: {
    updateFilms(state, films) {
      state.popular = films;
    },
    updateGenres(state, genres) {
      state.genres = genres;
    },
  },
  state: {
    popular: [],
    genres: [],
  },
  getters: {
    returnFilms(state) {
      return state.popular;
    },
    returnGenres(state) {
      return state.genres;
    },
  },
};

PopularMovies.vue

<template>
  <div class="container mx-auto px-4 pt-8">
    <div class="popular-movies">
      <h2
        class="uppercase tracking-wider text-lg text-orange-500 font-semibold"
      >
        Popular movies
      </h2>
      <div
        class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-4"
      >
        <div v-for="movies in returnFilms" :key="movies.id" class="mt-8">
          <img
            :src="'https://image.tmdb.org/t/p/w200' + movies.poster_path"
            alt="poster"
            class="hover:opacity-75 transition ease-in-out duration-150"
          />
          <div class="mt-2">
            <p class="text-lg mt-2 hover:text-gray-300">{{ movies.title }}</p>
            <div class="flex items-center mt1 text-sm text-gray-400">
              <svg class="fill-current text-orange-500 w-4" viewBox="0 0 24 24">
                <g data-name="Layer 2">
                  <path
                    d="M17.56 21a1 1 0 01-.46-.11L12 18.22l-5.1 2.67a1 1 0 01-1.45-1.06l1-5.63-4.12-4a1 1 0 01-.25-1 1 1 0 01.81-.68l5.7-.83 2.51-5.13a1 1 0 011.8 0l2.54 5.12 5.7.83a1 1 0 01.81.68 1 1 0 01-.25 1l-4.12 4 1 5.63a1 1 0 01-.4 1 1 1 0 01-.62.18z"
                    data-name="star"
                  ></path>
                </g>
              </svg>
              <span class="ml-1">{{ movies.vote_average * 10 }}%</span>
              <span class="mx-2">|</span>
              <span>{{ movies.release_date }}</span>
            </div>
            <div class="text-gray-300 text-sm">aaa</div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { mapGetters, mapActions } from 'vuex';

export default {
  name: 'Popular Movies',
  computed: {
    ...mapGetters(['returnFilms']),
  },
  methods: {
    ...mapActions(['getPopularFilms']),
  },
  async mounted() {
    this.getPopularFilms();
  },
};
</script>

<style lang="scss">
.text-orange-500 {
  color: #ed8936;
}
</style>

Screenshots enter image description here

enter image description here

My gets requests: https://api.themoviedb.org/3/movie/popular?api_key=d502a3d84eb533756ec099ef127a2acd&language=en-US&page=1

https://api.themoviedb.org/3/genre/movie/list?api_key=d502a3d84eb533756ec099ef127a2acd&language=en-US

Answer

Assuming you want the genreIds transformed to their name, within results.

Try this. I cannot test it unfortunately. I am on mobile.

async getPopularFilms({ commit }) {
      const res_movies = await fetch(
        'https://api.themoviedb.org/3/movie/popular?api_key=d502a3d84eb533756ec099ef127a2acd&language=en-US&page=1'
      );
      const { results } = await res_movies.json();
      commit('updateFilms', results);

      // Fetch genres
      const res_genres = await fetch(
        'https://api.themoviedb.org/3/genre/movie/list?api_key=d502a3d84eb533756ec099ef127a2acd&language=en-US'
      );
      const { genres } = await res_genres.json();

      const filmsWithGenres = results.map( ({genre_ids, ...rest}) => ({...rest, genre_ids: genre_ids.map(id => genres.find(genre => genre.id === id).name )}) )

      console.log(filmsWithGenres);
    },