how to wrap axios function and let parent to wait? - node.js

here's I've my axios function wrapped within a custom function:
async function getOrder(orderId) {
// ...
await axios({
method: 'post',
url: endpoint + "/mymethod",
data: request
}).then(function (response) {
var data = response.data.result;
return data;
}).catch(function (error) {
return { "error": error };
});
}
but if than i call that function:
router.get('/getOrder/:id', (req, res) => {
let result = getOrder(req.params.id);
res.json(result);
})
it returns nothing (since its async and don't wait the .then()).
what's the best way to wrap axios/async function and call from outside?

I think you're missing await in your codes:
router.get('/getOrder/:id', async (req, res) => {
let result = await getOrder(req.params.id);
res.json(result);
})
====================
[New Update]
for me in API function:
async getOrder(orderId) {
try {
const response = await axios.post(endpoint + "/mymethod")
return response.data
} catch (error) {
return { "error": error }
}
}
and get the result:
router.get('/getOrder/:id', async (req, res) => {
let result = await getOrder(req.params.id);
res.json(result);
})
===========
[New Update2] here is my sample async/await function with axios
const axios = require("axios")
async function getOrder(orderId) {
try {
const response = await axios.get("http://google.com")
return response.data
} catch (error) {
return { "error": error }
}
}
async function main() {
let result = await getOrder();
console.log(result, "##")
}
main()
====================
[New Update3] new Promise with axios:
const axios = require("axios")
async function getOrder(orderId) {
// try {
// const response = await axios.get("http://google.com")
// return response.data
// } catch (error) {
// return { "error": error }
// }
return await new Promise((resolve, reject) => {
axios({
method: 'get',
url: "http://google.com"
}).then(function (response) {
var data = response.data
resolve(data)
}).catch(function (error) {
reject({ "error": error })
});
})
}
async function main() {
let result = await getOrder();
console.log(result, "##")
}
main()

I think you are missing an await so you do not return a promise but wait for the result of getOrder to be passed in res.json :
router.get('/getOrder/:id', async (req, res) => {
let result = await getOrder(req.params.id);
res.json(result);
})

Related

How to return a value from axios outside axios function

I have a router.get which calls another function, like this:
router.get("/", (req, res) => {
const data = especiaisTest.getEspeciais();
console.log(data);
});
The function which is calling is this one:
function getEspeciais() {
db.query(async (tokenResponse) => {
try {
const response = await axios.get(URL, {
headers: {
Authorization: `Bearer ${tokenResponse.accessToken}`,
},
});
return response.data;
} catch (error) {
console.error(error);
}
});
}
Whenever i call it, I just get console.logged an undefined.
I tried returning a value outside the db.query function, for example:
function getEspeciais() {
db.query(async (tokenResponse) => {
try {
const response = await axios.get(URL, {
headers: {
Authorization: `Bearer ${tokenResponse.accessToken}`,
},
});
return response.data;
} catch (error) {
console.error(error);
}
});
return 'hello'
}
And it will display the 'hello' in the console. How can I get the response.data out of the db.query in order to be able to show the data?
Question codes.
router.get("/", (req, res) => {
const data = especiaisTest.getEspeciais();
console.log(data);
});
function getEspeciais() {
db.query(async (tokenResponse) => {
try {
const response = await axios.get(URL, {
headers: {
Authorization: `Bearer ${tokenResponse.accessToken}`,
},
});
return response.data;
} catch (error) {
console.error(error);
}
});
}
Should be:
router.get("/", async (req, res) => {
const data = await especiaisTest.getEspeciais();
async function getEspeciais() {
return db.query(async (tokenResponse) => {
Then you will see something else rather than undefined.
If return undefined, the db.query method return nothing.

Response doesn't wait for async function

I found the aproach how to put the async function into a router endpoint and tried to implement it but not suceed. E.g. this link zellwk.com
The server sends only empty string instead of a huge string that is on snippet.host.
async function downloadData(url) {
const options = {
'method': 'GET', 'url': url, 'headers': {}, formData: {}
};
let result = '';
await request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body)
result = response.body
});
return {error: 0, text: result}
}
app.get('/token/:token', jsonParser, async function (req, res) {
console.log(req.params.token) //Don't mind this token
try {
let message = await downloadData('https://snippet.host/xgsh/raw')
res.send(message)
} catch (e) {
console.log(e);
res.sendStatus(500);
}
});
How to make it wait for the download?
EDIT
I implemented node-fetch and got this:
{"error":0,"text":{"size":0}}
What did I wrong?
async function downloadData(url) {
const result = await fetch(url)
return {error: 0, text: result}
}
app.get('/token/:token', jsonParser, async function (req, res) {
console.log(req.params.token)
try {
let message = await downloadData('https://snippet.host/xgsh/raw')
res.send(message)
} catch (e) {
console.log(e);
res.sendStatus(500);
}
});
in case of fetch call the response body need to be parsed first which you are missing.
async function downloadData(url) {
const res = await fetch(url)
if (res && res.status != 200)
throw new Error("status code other than 200 received")
let json = await res.json()
return {error: 0, text: json}
}
app.get('/token/:token', async function (req, res) {
console.log(req.params.token)
try {
let message = await downloadData('https://snippet.host/xgsh/raw')
// let json = await message.json()
res.send(message)
} catch (e) {
console.log(e);
res.sendStatus(500);
}
});
i tried calling the api but every time it is returning 404 . so json cant be called in that case. but if 200 is returned then you call json and return that accordingly.
You can only usefully await a promise.
request doesn't return a promise, it takes a callback function instead.
This is one of the reasons that request was deprecated two years ago.
Replace request with something which supports promises such as node-fetch, the native fetch that was added to Node.js recently, or axios.
In case you must use request (eventhough it's deprecated); or in case you find a similar situation with a old function that doesn't return a promise; you can turn your request into a function that returns a promise.
Either write your own wrapper, in the form of
function requestPromise(options) {
return new Promise(
(resolve,reject) => request(options,
(err,response) => if (err) reject(err) else resolve(response)));
}
or, given that request's callback is in the form of function(err,response), directly use util.promisify
async function xxxx(...) {
try {
...
let response = await util.promisify(request)(options);
...
}
Because request isn't actually an async function that returns a Promise, you can create your own async version of request.
function asyncRequest(options) {
return new Promise((resolve, reject) => {
request(options, (err, response) => {
if (err) {
reject(err)
} else {
resolve(response)
}
})
})
}
Then in your project rewrite your downloadData function to be:
async function downloadData(url) {
const options = {
method: "GET",
url: url,
headers: {},
formData: {},
}
const result = await asyncRequest(options)
return { error: 0, text: result.body }
}

my asynchronous function returning Promise { <pending> } instead of a value?

log Promise { } instead of a value?
getdata function log : {
'start-time': '2021-11-29 08:54:00',
'end-time': '2021-11-29 10:54:00',
'entity-type': 'lun',
metric: 'throughput'
}
async function getdata(params) {
const data = await params
console.log("<<<<<<", data);
return data;
}
io.on("connection", async (data) => {
data.on("token", (token) => {
console.log(">>", token);
// tokenData(tokenid)
});
data.on("params", async (params) => {
let formData = await params
getdata(formData)
// console.log("<<<", params);
})
})
console.log("PPPP", getdata() ); : Promise { <pending> }

Fastify async try catch does not resolve

I have simple route:
fastify.post('/subscribe', {
schema: subscribeSchema,
handler: async (req, reply) => {
try {
const events = req.body.events;
const allEventsProcessingData = await Promise.all(events.map(async (ev) => {
return {
event: ev,
feedEventsData: await getFeedEventData(ev),
feedMainMarketsData: await getFeedEventMainMarketsData(ev),
}
}));
// process HTML by events data
// allEventsProcessingData
const compiledHTML = '';
return reply.send(compiledHTML);
} catch (e) {
console.log('e', e);
return reply.send(HTTP_RESPONSES.FAIL);
}
}
});
When error happens, the response does not send, why is it? And how to send it? Tried this https://github.com/fastify/fastify/issues/1864#issuecomment-534233381, but it did not work.

node js call a promise function inside a chain .then

Hello I am new working with asynchronous calls I hope you can help me.
I have a .then chain where I want to call in the middle of the chain a function that returns a promise but it happens to me that the chain does not wait for it to have the result of the promise function and continues without waiting
var User = require('../models/user_model');
var mapbox = require('./helper/request_api_mapbox');
findOne_mapbox: (req, res) => {
User.findById(req.params.id)
.then(user => {
...
return user.address;
})
.then(function (adress_to_mapbox)
{
// mapbox.connect_mapbox returns a promise
mapbox.connect_mapbox(adress_to_mapbox)
.then(mapbox_coordinates => {
//inside this console.log is not read it
console.log("2 then mapbox_coordinates ", mapbox_coordinates)
return Promise.resolve(body);
})
})
.then( mapbox_coordinates => {
// in this console.log mapbox_coordinates returns undefined
console.log("last promise mapbox_coordinates",
mapbox_coordinates)
// I want to return mapbox_coordinates
return res.status(200).send({
"response": "I only receive this string "
});
})
}
the promise function is:
'use strict'
const rp = require('request-promise');
const access_token_mapbox = 'bla bla bla private';
function connect_mapbox(adress_to_mapbox) {
return new Promise((resolve, reject) => {
var options = {
method: 'GET',
uri: 'https://api.mapbox.com/geocoding/v5/mapbox.places/' + adress_to_mapbox + '.json?access_token=' + access_token_mapbox,
json: true // Automatically stringifies the body to JSON
};
rp(options)
.then(body => {
if (body.hasOwnProperty('errcode') && body.errcode != 0) {
return Promise.reject(body);
}
console.log("inside connect_mapbox function on mapbox_model 2", body)
return Promise.resolve(body);
})
.catch(err => {
debug(err);
return Promise.reject(err);
})
})
}
module.exports = { connect_mapbox };
Inside the promise function I can see in my console.log that it makes the api call properly and the response body is ok.
I am starting in the programming, I solved the problem in the following way although I don't know if it is the most correct
I solved it by converting the connect_mapbox promise function to async await and the .then chain to async await like so:
'use strict'
const rp = require('request-promise');
const access_token_mapbox = 'bla bla bla private';
async function connect_mapbox(adress_to_mapbox) {
try {
var options = {
method: 'GET',
uri: 'https://api.mapbox.com/geocoding/v5/mapbox.places/' + adress_to_mapbox + '.json?access_token=' + access_token_mapbox,
json: true // Automatically stringifies the body to JSON
};
let response = await rp(options);
console.log("inside connect_mapbox function on mapbox_model", response)
if (response.hasOwnProperty('errcode') && body.errcode != 0) {
return Promise.reject(response);
}
return Promise.resolve(response);
}catch(error) {
return Promise.reject(error);
}
}
module.exports = { connect_mapbox };
And the .then chain like
var User = require('../models/user_model');
var mapbox = require('./helper/request_api_mapbox');
findOne_mapbox: (req, res) => {
User.findById(req.params.id)
.then(user => {
...
return user.address;
})
.then(async function (adress_to_mapbox)
{
console.log("adress_to_mapbox thit could be deleted", adress_to_mapbox)
let mapbox_response = await mapbox.connect_mapbox(adress_to_mapbox)
console.log("async mapbox_response", mapbox_response)
return res.status(200).send({
mapbox_response
});
})
...
}

Resources