Get body of GET request (NodeJS + axios) - javascript

Here's my request:
axios.get(BASE_URI + '/birds/random', {Stuff: "STUFF"})
.then(randBird=>{
const birdData = randBird.data
const bird = {
age: birdData.age,
bio: birdData.profile.bio,
displayname: birdData.profile.displayname,
species: birdData.profile.species,
_id: birdData._id
}
this.setState({currentBird:bird})
})
Here's what happens on my router (on '/birds'):
birdRouter.route('/random').get((req, res)=>{
console.log('req.body = ', req.body)
User.count().exec((err, num)=>{
if(err){
console.log(err)
return res.send({error: err})
}
const random = Math.floor(Math.random() * num)
User.findOne().skip(random).exec((err, bird)=>{
if(err){
console.log(err)
return res.send({error: err})
}
console.log(bird)
res.send(bird)
})
})
Really, the only lines that are worth paying attention to in both snippets are the first and first two (for the first and second snippet, respectively).
The request goes through, but my console.log shows this:
req.body = {}
What did I do wrong here?

Some browsers and libraries don't support HTTP get method with a body. You can switch to POST/PUT and see if it works as expected.

Usually in GET method we are not passing body data. instead of body data you can pass in query string. and also if you are using express server than you need to install a package body-parser to get data in body. please take a reference of issue posted in axios

Related

Is it good practice to access req.query in a PUT request?

I'm building a website with an API using NEXTjs. For a single element, I use the dynamic api route provided by NEXTjs and I'm currently using that route both for getting an element and updating element.
In both the GET and PUT request, I use the req.query.fetchId to get or update the element.
However, I see req.query mostly used for GET requests and in POST/PUT request it's usually req.body being used.
It seems to work, but I'm wondering if I should?
This is the URL for the request: api/items/[fetchId]
And this is my code for the PUT request so far:
if (req.method==="PUT") {
try {
const { db } = await connectToDatabase();
const videoGamesCollection = db.collection("videogames");
const result = await videoGamesCollection
.updateOne({ _id: ObjectId(req.query.fetchId) }, {$inc: {}})
res.status(200).json({ message: "success", result: result });
} catch (error) {
res.status(error.code ?? 502).send({
message: error.message ?? "Something went wrong.",
});
}
}

PG-Promise Proc Erroring Out with Unknown Parameter Type

We are attempting to write a PostgreSQL Procedure to insert data into a table. We have created the procedure and ran said procedure with the variables below and it inserts just fine. However, when we try to use pg-promise with our express server, our string parameters are being read as unknown. When we iterate over the post body, we see that each parameter is reading as the type we expect to go in, and PostgreSQL is reading integer correctly, but it isn't reading string correctly. I've attempted to use the as.text function and it sends in the parameter value as "''" but that still reads as unknown. Is there something we are missing to successfully post the data?
let createInspection = async (req, res, next) => {
try {
let params = [];
for (let prop in req.body) {
console.log(typeof req.body[prop]);
params.push(req.body[prop]);
}
console.log(params)
let data = await db.proc('Inspections_Create', params);
res.status(200)
.json({
status: 'success',
data: data,
message: 'Inserted Inspection'
});
}
catch (error) {
return next(error);
}
}

Long running Node REST API takes much time to respond

I have a Rest API in node.js that takes much time to respond because it sends a request to suppliers vendor and once the response is fully prepared then it returns the result what I want is as the result is being prepared it should be able to display it on the front react side. Thanks in advance for any help and your time
here is my controller
module.exports.search = async (req, res) => {
try {
let params = req.query;
params = _.extend(params, req.body);
const result = await modules.Hotel.Search.search(req.supplierAuth, params);
res.json(result);
} catch (e) {
global.cli.log('controller:hotels:search: ', e);
res.status(500).json({ message: e.message });
}
};
here is my front side service
export const getHotels = (filters, options = {}) => {
const queryString = new URLSearchParams(options).toString();
return post(`/api/hotels/search?${queryString}`, filters);
};
The best solution is to use streams and pipe() the results as they come into express's res object, similar to this guy's approach.
You'll have to modify the modules.Hotel.Search.search(....) and make that use streams.

Append a query param to a GET request?

I'm trying to make a simple API that calls another API that will return some information. The thing is, in order to connect to the second API, I need to attach query parameters to it.
So what I've tried to do so far is to use an axios.get in order to fetch the API. If I didn't need to add queries on top of that, then this would be really simple but I'm having a really hard time trying to figure out how to attach queries on top of my request.
I've created an object that pulled the original query from my end and then I used JSON.stringify in order to turn the object I made into a JSON. Then, from my understanding of Axios, you can attach params my separating the URL with a comma.
On line 6, I wasn't sure if variables would carry over but I definitely can't have the tag var turned into the string "tag", so that's why I left it with the curly brackets and the back ticks. If that's wrong, then please correct me as to how to do it properly.
the var tag is the name of the query that I extracted from my end. That tag is what needs to be transferred over to the Axios GET request.
app.get('/api/posts', async (req, res) => {
try {
const url = 'https://myurl.com/blah/blah';
let tag = req.query.tag;
objParam = {
tag: `${tag}`
};
jsonParam = JSON.stringify(objParam);
let response = await axios.get(url, jsonParam);
res.json(response);
} catch (err) {
res.send(err);
}
});
response is SUPPOSED to equal a JSON file that I'm making the request to.
What I'm actually getting is a Error 400, which makes me think that somehow, the URL that Axios is getting along with the params aren't lining up. (Is there a way to check where the Axios request is going to? If I could see what the actual url that axios is firing off too, then it could help me fix my problem)
Ideally, this is the flow that I want to achieve. Something is wrong with it but I'm not quite sure where the error is.
-> I make a request to MY api, using the query "science" for example
-> Through my API, Axios makes a GET request to:
https://myurl.com/blah/blah?tag=science
-> I get a response with the JSON from the GET request
-> my API displays the JSON file
After looking at Axios' README, it looks like the second argument needs the key params. You can try:
app.get('/api/posts', async (req, res, next) => {
try {
const url = 'https://myurl.com/blah/blah';
const options = {
params: { tag: req.query.tag }
};
const response = await axios.get(url, options);
res.json(response.data);
} catch (err) {
// Be sure to call next() if you aren't handling the error.
next(err);
}
});
If the above method does not work, you can look into query-string.
const querystring = require('query-string');
app.get('/api/posts', async (req, res, next) => {
try {
const url = 'https://myurl.com/blah/blah?' +
querystring.stringify({ tag: req.params.tag });
const response = await axios.get(url);
res.json(response.data);
} catch (err) {
next(err);
}
});
Responding to your comment, yes, you can combine multiple Axios responses. For example, if I am expecting an object literal to be my response.data, I can do:
const response1 = await axios.get(url1)
const response2 = await axios.get(url2)
const response3 = await axios.get(url3)
const combined = [
{ ...response1.data },
{ ...response2.data },
{ ...response3.data }
]

NodeJs app "hanging" or "freezing" whenever an error occurs

When I make multiple post requests to my nodejs server and all of the parameters are correct, everything works fine (and doesnt freeze) but when I make multiple post requests with incorrect parameters that gives an error, my nodejs server just freezes/hangs for a few minutes. Why is this?
Here is my code btw
app.post('/pushtransaction', function(req, res) {
console.log(req.body);
console.log(5);
if (req.body.sigs) {
let sigver = xmf.modules.ecc.Signature.from(req.body.sigs).toString();
let lasig = [sigver];
console.log(req.body.packedTr);
let transi = JSON.parse(req.body.packedTr);
//let sigver = req.body.sigs;
let package = {
compression: 'none',
transaction: transi,
signatures: lasig
}
console.log(package);
//Pushes tx in correct format
xmf.pushTransaction(package).then(result=>{
res.send(result);
res.end();
console.log(result);
}).catch(err => {
console.log(err)
});
}
})
When your error is encountered, your Node server does not know what to do other than console.log() the error. It needs to end that request and send some response. You can res.status(400).send({ error: err }) when you're within the catch.
Make sure res.send() method gets called every time in your request.
Updated Javascript:
app.post('/pushtransaction', function(req, res) {
console.log(req.body);
console.log(5);
if (req.body.sigs) {
let sigver = xmf.modules.ecc.Signature.from(req.body.sigs).toString();
let lasig = [sigver];
console.log(req.body.packedTr);
let transi = JSON.parse(req.body.packedTr);
//let sigver = req.body.sigs;
let package = {
compression: 'none',
transaction: transi,
signatures: lasig
}
console.log(package);
//Pushes tx in correct format
xmf.pushTransaction(package).then(result=>{
res.send(result);
res.end();
console.log(result);
}).catch(err => {
console.log(err);
res.status(400).send();
});
}
res.status(400).send();
})
Additionally you don't have to call res.end() if you call res.send(). see Must res.end() be called in express with node.js?
Adding to other answers, you can add a middleware for timeouts, if any service fails to respond in some time, like
var timeout = require('connect-timeout');
app.use(timeout('5s'));

Categories

Resources