I want to use async/await inside this promise.allSettled to convert currency by fetching some api or databased stored currency rates.
like i want to use await here like this, but not sure where to put async.
arrcars["price_client"] = await forexService.convertCurrency(item.regular_price, "EUR", userCurrency);
I have posted my entire code. need some guidance here.
This is controller
const httpStatus = require('http-status');
const pick = require('../utils/pick');
const catchAsync = require('../utils/catchAsync');
const async = require('async');
const axios = require('axios');
const { talixoService } = require('../services');
const { iwayService } = require('../services');
const { forexService } = require('../services');
const searchCars = function (req, res) {
const talixoData = talixoService.findTalixoCars(req.body) //call talixo api in services
const iwayData = iwayService.findiWayCars(req.body) //call iwaytransfers api in services
if (req.query.usercurrency) {
var userCurrency = req.query.usercurrency;
} else {
var userCurrency = "INR";
}
return Promise.allSettled([talixoData, iwayData]).then(([restalixo, resiway]) => {
const taxiresults = [];
if (restalixo.status === "fulfilled") {
//console.log(restalixo.value.data);
if (restalixo.value.data.taxis.length) {
restalixo.value.data.taxis.forEach(function (item) {
arrcars = {};
arrcars["carname"] = item.car_model;
arrcars["originprice"] = item.regular_price;
arrcars["price_client"] = forexService.convertCurrency(item.regular_price, "EUR", userCurrency);
arrcars["discountprice_client"] = forexService.convertCurrency(item.discount_price, "EUR", userCurrency);
arrcars["packageId"] = item.id;
arrcars["image"] = item.image_url;
arrcars["freewaittime"] = item.included_waiting_time;
arrcars["maxluggage"] = item.luggage;
arrcars["maxpassengers"] = item.seats;
arrcars["discountprice"] = item.discount_price;
arrcars["vehicletype"] = item.vehicle_type;
arrcars["vendor"] = "Talixo";
arrcars["vehicleremarks"] = "Or Similar";
taxiresults.push(arrcars);
});
}
if (restalixo.value.data.limousines.length) {
restalixo.value.data.limousines.forEach(function (item) {
arrcars = {};
arrcars["carname"] = item.car_model;
arrcars["originprice"] = item.regular_price;
arrcars["price_client"] = forexService.convertCurrency(item.regular_price, "EUR", userCurrency);
arrcars["discountprice_client"] = forexService.convertCurrency(item.discount_price, "EUR", userCurrency);
arrcars["packageId"] = item.id;
arrcars["image"] = item.image_url;
arrcars["freewaittime"] = item.included_waiting_time;
arrcars["maxluggage"] = item.luggage;
arrcars["maxpassengers"] = item.seats;
arrcars["discountprice"] = item.discount_price;
arrcars["vehicletype"] = item.vehicle_type;
arrcars["vendor"] = "Talixo";
arrcars["vehicleremarks"] = "Or Similar";
taxiresults.push(arrcars);
});
}
}
//iwaytransfers supplier data
if (resiway.status === "fulfilled") {
//console.log(resiway.value.data);
if (resiway.value.data.result.length) {
resiway.value.data.result.forEach(function (item) {
var imgsrc = "https://iwayex.com/images/cars/";
arrcars = {};
arrcars["carname"] = item.car_class.models[0];
arrcars["originprice"] = item.price;
arrcars["price_client"] = forexService.convertCurrency(item.price, "EUR", userCurrency);
arrcars["discountprice_client"] = forexService.convertCurrency(item.price, "EUR", userCurrency);
arrcars["packageId"] = item.price_uid;
arrcars["image"] = imgsrc + item.car_class.photo;
arrcars["freewaittime"] = item.allowable_time;
arrcars["maxluggage"] = "";
arrcars["maxpassengers"] = item.car_class.capacity;
arrcars["discountprice"] = item.price;
arrcars["vehicletype"] = item.vehicle_type;
arrcars["vendor"] = "iway Transfers";
arrcars["vehicleremarks"] = "Or Similar";
taxiresults.push(arrcars);
});
}
}
if (taxiresults.length) {
sortedresult = taxiresults.sort(function (a, b) {
return a.discountprice - b.discountprice;
});
res.status(200).send(sortedresult)
}else{
res.status(200).send({})
}
});
}
module.exports = {
searchCars
}
this is the result sample i am getting.
{
carname: "Toyota Prius"
discountprice: 27.5
discountprice_client: {}
freewaittime: 45
image: "https://static.talixo.de/images/vehicles/economy.png"
maxluggage: 3
maxpassengers: 3
originprice: 27.5
packageId: "16021"
price_client: {}
vehicleremarks: "Or Similar"
vehicletype: "limo"
vendor: "Talixo"
}
here the problem is, i expect
discountprice_client: Converted Number,
but i am getting blank object there as can be seen in above result sample. i have been using this in another function with async await, then it works fine. but in this case, i am not sure how to put async/await.
this is inside
forex.service.js
const convertCurrency = async (amount, basecurrency, reqCurrency) => {
if (basecurrency === reqCurrency) {
let result = Math.round(amount) + ' ' + reqCurrency;
return result;
} else {
const reqForexData = await getForexbyISO(reqCurrency);
const baseForexData = await getForexbyISO(basecurrency);
const amountInUSD = amount / baseForexData.forexRate;
const amountInreqC = amountInUSD * reqForexData.forexRate;
let result = Math.round(amountInreqC) + ' ' + reqCurrency;
return result;
}
}
module.exports = {
convertCurrency
}
You could do:
// notice the `async` before `function`
resiway.value.data.result.forEach(async function (item) {
// ...
arrcars = {};
arrcars["price_client"] = await forexService.convertCurrency(item.price, "EUR", userCurrency);
arrcars["discountprice_client"] = await forexService.convertCurrency(item.price, "EUR", userCurrency);
// ...
});
But it can lead to unexpected behaviours
I would do this
// add missing `async`
return Promise.allSettled([talixoData, iwayData]).then(async ([restalixo, resiway]) => {
// ...
// await for all loop at once to avoid odd side effects
await Promise.all(resiway.value.data.result.map(async function (item) {
// ...
arrcars = {};
arrcars["price_client"] = await
forexService.convertCurrency(item.price, "EUR", userCurrency);
arrcars["discountprice_client"] = await
forexService.convertCurrency(item.price, "EUR", userCurrency);
// ...
}));
// ...
});
simplify your services
You are writing the Talixo and Iway services but using the result is difficult. Instead of returning the entire response, return the fields that matter to your consumer -
// services/talixo_service.js
async function findTalixoCars(query) {
const result = await // ... perform request
return result.value.data ?? [] // <- return relevant data
}
Notice we use return _____ ?? []
return _____ ?? []
to ensure that an array is always returned -
// services/iway_service.js
async function findiWayCars(query) {
const result = await // ... perform request
return result.value.data.result ?? [] // <- return relevant data
}
searchCars
With simplified services, we write a high-level implementation of searchCars
. Instead of using Promise.allSettled
we can use .catch(_ => [])
on potential failures to guarantee we have an array result. This reduces the need for logical checks and code branches to make the code more declarative and less prone to errors -
async function searchCars(req, res) {
const [talixo, iway] = await Promise.all([
talixoService.findTalixoCars(req.body).catch(_ => []),
iwayService.findiWayCars(req.body).catch(_ => [])
])
const userCurrency = req.query.usercurrency ?? "INR"
const taxis = [
...await Promise.all(talixo.taxis.map(item => fromTalixo(item, userCurrency))),
...await Promise.all(talixo.limousines.map(item => fromTalixo(item, userCurrency))),
...await Promise.all(iway.map(item => fromIway(item, userCurrency)))
]
res.status(200).send(
taxis.sort((a,b) => a.discountprice - b.discountprice)
)
}
data mapping
The search function above depends on fromTalixo
and fromIway
. These mapping functions reduce code complexity and repitition and gives us a good conceptual model for how data gets mapped from the remote services to our local data -
async function fromTalixo(data, userCurrency) {
return {
carname: data.car_model,
originprice: data.regular_price,
price_client: await forexService.convertCurrency(data.regular_price, "EUR", userCurrency),
discountprice_client: await forexService.convertCurrency(data.discount_price, "EUR", userCurrency),
packageId: data.id,
image: data.image_url,
freewaittime: data.included_waiting_time,
maxluggage: data.luggage,
maxpassengers: data.seats,
discountprice: data.discount_price,
vehicletype: data.vehicle_type,
vendor: "Talixo",
vehicleremarks: "Or Similar",
}
}
async function fromIway(data, userCurrency) {
return {
carname: data.car_class.models[0],
originprice: data.price,
price_client: await forexService.convertCurrency(data.price, "EUR", userCurrency),
discountprice_client: await forexService.convertCurrency(data.price, "EUR", userCurrency),
packageId: data.price_uid,
image: `https://iwayex.com/images/cars/${data.car_class.photo}`,
freewaittime: data.allowable_time,
maxluggage: "",
maxpassengers: data.car_class.capacity,
discountprice: data.price,
vehicletype: data.vehicle_type,
vendor: "iway Transfers",
vehicleremarks: "Or Similar",
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.