How to return from promise before non-async function return?

Issue

At some point in the code, if a condition is true, I need to use data from external API, which is fetched asynchronously like this:

# ./helper/currencyConverter.js

const axios = require('axios').default;

const convert = async (curr, amount) => {
  try {
    const response = await axios.get('https://api.example.com/endpoint');
    const data = response.data;

    // do conversion

    return convertedAmount;

  } catch (error) {
    throw new Error(error);
  }
}

module.exports = { convert }

The module above is called from a non-async function if certain condition is met, then return data processed by the async function, otherwise return unprocessed data, as demonstrated here:

# ./models/calculator.js
const currencyConverter = require('../helpers/currencyConverter');

const calculate = data => {

  const amount = data.amount;

  if (true) {
    currencyConverter.convertToEur(currency, amount).then(convertedAmount => {
      return convertedAmount;
    });
  }

  return amount; 
}

The problem is that return amount always returns earlier than return convertedAmount. How do I make the return convertedAmount to return if the condition is true?

Solution

You can just return a promise and resolve it when you execute the calculate function.

const calculate = data => {
  const amount = data.amount;
  let condition = true
  return condition ? 
    currencyConverter.convertToEur(currency, amount) : Promise.resolve(amount)
}

// resolve the promise returned by calculate function.
calculate(data).then(res => console.log(res))

Or async/await syntax to stop return the function until it is processed by the convertToEur function.

const calculate = async data => {
  const amount = data.amount;

  if (true) {
    amount = await currencyConverter.convertToEur(currency, amount)
  }

  return amount; 
}

Answered By – Mina

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published