SheWolf
SheWolf

Reputation: 95

How do I call two different REST api endpoints simultaneously and display the data from both on one endpoint of my app?

I am building a simple application for my portfolio using The Movie Database api. In my GET /movie route, I want to get and display the data about the movie, and the names and photos of the cast members, however the data for the movie and the data for the cast members belong two separate endpoints of the api, and I am at a complete loss as to how to access both response data sets under a single endpoint in my app.

I cannot call axios.get() on both endpoints under the /movie route because I will get a "Headers already sent" error, and I have tried to write a function that uses axios.get for 1 endpoint that returns the response and gets called in my GET /movie route, but that causes the entire GET route to return undefined.

Here is my current code for my /movie route that is incorrect, but closely conveys what I am trying to accomplish

const express = require('express');
const router = express.Router();
const axios = require('axios');
const api_key = require('../config/keys').api_key;
const imgURL = "http://image.tmdb.org/t/p/";
const dateFormat = require('../config/dateFormat');

getActors = movie_id => {
    axios.get(`https://api.themoviedb.org/3/movie/${movie_id}/credits?api_key=${api_key}&language=en-US`)
        .then(res => { 
            return res.data;
         }).catch(err => console.log(err.message));
}

router.get('/:id', (req, res) => {
    const id = req.params.id
    axios.get(`https://api.themoviedb.org/3/movie/${id}?api_key=${api_key}&language=en-US`)
        .then(res => {
            const movieData = res.data;
            const actors = getActors(id); //calling above function here, but returns undefined and hangs the application
            res.render('movie', {movieInfo: movieData, imgURL: imgURL, releaseDate: dateFormat(movieData.release_date), actors: actors})
        })
        .catch(err => console.log(err.status_message))
});

module.exports = router;

any help is greatly appreciated.

Upvotes: 2

Views: 1791

Answers (2)

Oscar Calderon
Oscar Calderon

Reputation: 989

You can use axios.all to concatenate several promises and executing them in parallel. Then, once all the added requests have been finished, you can handle with the then promise the result of all of them. For instance, in your code:

const express = require('express');
const router = express.Router();
const axios = require('axios');
const api_key = require('../config/keys').api_key;
const imgURL = "http://image.tmdb.org/t/p/";
const dateFormat = require('../config/dateFormat');

axios.all([
    axios.get(`https://api.themoviedb.org/3/movie/${movie_id}/credits?api_key=${api_key}&language=en-US`),
    axios.get(`https://api.themoviedb.org/3/movie/${id}?api_key=${api_key}&language=en-US`)
  ])
  .then(axios.spread((actorsRes, moviesRes) => {
    // Your logic with each response
  });

module.exports = router;

Upvotes: 2

Jason Kim
Jason Kim

Reputation: 19031

I see that getActors is currently returning null. Change it to...

const getActors = movie_id => {
    return axios.get(`https://api.themoviedb.org/3/movie/${movie_id}/credits?api_key=${api_key}&language=en-US`)
        .then(res => { 
            return res.data;
         }).catch(err => console.log(err.message));
}

Another problem is calling of getActors function. It's a function that contains asynchronous function axios.get(). Change that to ..

router.get('/:id', (req, res) => {
    let movieData;
    const id = req.params.id
    axios.get(`https://api.themoviedb.org/3/movie/${id}?api_key=${api_key}&language=en-US`)
        .then(res => {
            movieData = res.data;
            return getActors(id);

        })
        .then(actors => {
            res.render('movie', {movieInfo: movieData, imgURL: imgURL, releaseDate: dateFormat(movieData.release_date), actors: actors})
        })
        .catch(err => console.log(err.status_message))
});

Upvotes: 2

Related Questions