Catch Return of Async Function in External File

Asked

Viewed 39 times

-1

I have 2 files in both async use / await and return a promisse.
So far so good.
But my question is what to call them in Controller.
I’m managing to return all recipes, however, I’m not able to add the parameter gif on the return of the object in the API.
I tried to pass await inside the property gif: await but I was unsuccessful.

Imsomnia

const getRecipes = require('../services/recipePuppy');
const getGifFromRecipe = require('../services/giphy');


module.exports = {
    async getRecipes(request, response) {
        const clientRequest = request.query;

        const ingredientsList = clientRequest.i.split(',');

        const recipesResponse = await getRecipes.getRecipesFromIngredients(ingredientsList);

        if (recipesResponse) {
            response.json({
                keywords: ingredientsList,
                recipes: recipesResponse.results.map((recipe) => {
                    return {
                        title: recipe.title,
                        ingredients: recipe.ingredients,
                        link: recipe.href,
                        // gif: como obter o GIF?
                    }
                })
            });
        }
    }
}

Service code giphy:

const axios = require('axios');

module.exports = {
    async getGif(search) {
        const response = await axios.default.get(`https://api.giphy.com/v1/gifs/search?api_key=${process.env.GIPHY_API}&q=${search}&limit=1&offset=0&rating=g&lang=${process.env.GIPHY_LANGUAGE}`);

        return response.data;
    }
}

1 answer

1


I didn’t really understand where the search to the getGif, but supposing it was a field of the recipe itself. I would do something more or less like this:

const bluebird = require('bluebird');

const getRecipes = require('../services/recipePuppy');
const getGifFromRecipe = require('../services/giphy');

module.exports = {
  async getRecipes(request, response) {
    const clientRequest = request.query;
    const ingredientsList = clientRequest.i.split(',');

    const recipesResponse = await getRecipes.getRecipesFromIngredients(ingredientsList);

    if (recipesResponse) {                
      const res = await bluebird.map(recipesResponse.results, async (recipe) => {
        const gif = await getGifFromRecipe.getGif(recipe.search);
        return {
          title: recipe.title,
          ingredients: recipe.ingredients,
          link: recipe.href,
          gif,
        };
      }, { concurrency: 10 });
    
      response.json(res);
    }
  }
}

I used the Bluebird as it greatly facilitates these operations with Promises. Using the parameter concurrency there is optional, but it is very nice, because it makes it possible to parallel the calls to the external service that gets the gifs, which speeds up the response time.

If the use of Bluebird is impossible, the solution would be to make a map of recipes for an array of Promises of getGif, then a await in a Promise.all of this array, and finally, the generation of the answer. I can try to put an example of this model here too, if necessary.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.