I'm having trouble to understand why my callback function needs 2 parameters, i.e. one for the request and one for the response?
For instance i bind a callback function to my server:
server.on("request", doThis(req, resp));
In my opinion he needs only one parameter (req for example here) to store the req information (GET, POST, url, etc.). Why does he need a second for response? I write the information in resp. (i.e. the server, so my other scripts) and not the client.
Every time a request is coming in, the callback function is invoked and so the req parameter is set. Am i wrong? But why do I need the response parameter? My server needs it when he is responding but not when I'm reading/saving the request informations?
The Response parameter is what's generally used to send back a response.
A request comes in, you get the request's data in the req (first) param and you then use the res (second) param to send back a response like:
server.on('message', function(req, res){
res.send('hello your ip is: ' + req.client.ip);
})
This is all dependant on your framework but in expressjs this is how it works (more or less).
To answer your question, you don't need it - you can simply not issue it as a parameter (although it will still be accessible) if you don't plan on responding (which is weird and quite uncommon)
server.on('message', function(req){
console.log('someone requested "message"')
})
Generally speaking, you would always send back a response although the end user might never visually see it, it's just to confirm that the action has been completed successfully.
server.on('save', function(req, res){
saveFile(req.file)
res.sendStatus(200)
})
Additionally, you could check if the process completed successfully - if it did you'd send back a success message, otherwise send back an error message.
server.on('save', function(req, res){
saveFile(req.file, function(error){
if(error) res.sendStatus(500)
res.sendStatus(200)
})
})
Related
I've got a small Express JS api that I'm building to handle and process multiple incoming requests from the browser and am having some trouble figuring out the best approach to handle them.
The use case is that there's a form, with potentially up-to 30 or so people submitting form data to the Express JS api at any given time, the API then POSTS this data of to some place using axios, and each one needs to return a response back to the browser of the person that submitted the data, my endpoint so far is:
app.post('/api/process', (req, res) => {
if (!req.body) {
res.status(400).send({ code: 400, success: false, message: "No data was submitted" })
return
}
const application = req.body.Application
axios.post('https://example.com/api/endpoint', application)
.then(response => {
res.status(200).send({ code: 200, success: true, message: response })
})
.catch(error => {
res.status(200).send({ code: 200, success: false, message: error })
});
})
If John and James submit form data from different browsers to my Express JS api, which is forwarded to another api, I need the respective responses to go back to the respective browsers...
Let's make clear for you, A response of a request will only send to the requester, But if you need to send a process request and send a response like, hey i received your request and you can use another get route to get the result sometimes later, then you need to determine which job you mean. So You can generate a UUID when server receives a process request and send it back to the sender as response, Hey i received your process request, you can check the result of process sometimes later and this UUID is your reference code. Then you need to pass the UUID code as GETparam or query param and server send you the correct result.
This is the usual way when you are usinf WebSockettoo. send a process req to server and server sends back a reference UUID code, sometime later server sends the process result to websocket of requester and says Hey this is the result of that process with that UUID reference code.
I hope i said clear enough.
I am using axios to do AJAX calls to my Express web server. Whenever I make a post request and pass in a piece of data, the data is for some reason never sent to the server. Whenever I check the request.body, no data is ever there even though I clearly added it.
<script>
axios.post("/api/users", {
firstname: 'fred'
})
.then(function(res){
console.log(res.data);
})
.catch(function(err){
console.log(err);
})
</script>
The above is the AJAX Post request I am making with axios. As you can see, I passed in a piece of data: "firstname" to be sent to "/api/users".
app.post("/api/users", function(req, res){
console.log(req.body);
res.send({newData: req.body.firstname});
});
This is my very simple post route that it is sending to. I am simply passing the data that I sent back to the client. Whenever this runs, "firstname" is never found. When I check the console.log, the req.body is empty, and the .then console.log on the client side only shows some random "_proto_" object, but not what I sent. I've done exactly as the documentation says, why isn't "firstname" going through??
EDIT: I just tried with fetch, it still didn't work. It seems like any AJAX request is just not working right, the data doesn't go through.
I will demonstrate my problem with this simplified code:
app.get('/test', (req, res) => {
let x = req.query.someVar;
app.post('/test', (req, res) => {
console.log(x);
});
res.send(`Hello ${req.query.someVar}`);
});
The first time this code runs, the POST callback function saves a reference to x which is whatever I pass as query parameters. if I change the query parameters, send another GET request it will be updated in the server's response i.e.res.send(Hello ${req.query.someVar}); but a POST request will still log the original x value to the console.
Why is it behaving this way? I have tried many things like passing by objects and through other functions, etc..
I am familiar with how closures work, but obviously not entirely as this is most definitely a problem with the POST call back preserving the value of the query parameters and not updating them.
Thanks.
I'm not sure what you are trying to do. No one defines a POST inside of a GET, they do that at the root level, unless you want the GET request to change the behavior of your server. app.post means 'add a new route to handle a POST'. Perhaps you wanted to actually send an HTTP request from the GET handler?
If you want the behavior to change maybe just handle the POST at the root level and set a global flag in the GET handler to indicate that POST should do something different with subsequent requests.
Here in the GET /facebook route i receive the authorization code from front-end after receiving that, i have to make a POST request to /facebook/signin
How can I redirect GET /facebook to POST /facebook/signin
router.get('/facebook', (req, res) => {
// res.send(req.query.code);
res.redirect('/facebook/sign'); // = GET /facebook/sign
});
POST route
router.post('/facebook/sign', (req, res, next) => {
console.log(req.query.code);
// i will do mine stuff....
});
You can also write 1 handler method and use it in both routes;
function doFacebookSignIn(req, res) {
// Your code here.
}
or
// Must be defined before using it in code.
var doFacebookSignIn = function(req, res) {
// Your code here.
};
router.get('/facebook', doFacebookSignIn);
router.post('/facebook/sign', doFacebookSignIn);
But as I pointed out in the comments, you should be aware that when using a request body in a GET request, there are some things to consider.
You cannot redirect GET to POST, a redirect is used to notify an HTTP client that a resource has changed location and should attempt the same request using the new location.
It is noted in the RFC that in some cases POST will be downgraded to GET when the request is re-issued.
Note: When automatically redirecting a POST request after
receiving a 301 status code, some existing HTTP/1.0 user agents
will erroneously change it into a GET request.
If a POST request is expected on the server, then the client should send a POST request rather than a GET request.
router.post('/register', function(req, res) {
User.register(new User({ username : req.body.email }), req.body.password, function(err, account) {
if (err) {
return res.render('register', { account : account });
}
passport.authenticate('local')(req, res, function () {
res.redirect('/');
});
});
});
I get the general idea of this routing post, but I don't understand all of it.
What information generally comes in through req? It seems like if I do req.body.email and if in the body of my register html page I've submitted a form with an email and password field, I can simply access them this way?
And in the function(err, account) callback, where exactly is it getting the err and account variables? I've never really understood for the callback functions how the variables were decided or what even they are, it seems like when you route it somehow takes two variables err and account?
Thanks so much!
1st-
Well you should read the ExpressJS documentation and see the difference between body, query and params but basically goes like this
body refers to the body of the request, which is the submitted data through POST or PUT
query refers to the search part of the url or query string everything after the "?"
params refers to the part of the path that is parameterized.
hope that gives you a clue of how and where to look for the information
2nd- is nodes convention that always the first variables passed to a callback is the error variablem the rest is according to the function in this case is account because the function is suppose to create db account and return the entire account information so ir can bu used by the callback
What information generally comes in through req?
The request object (req) comes with data on the request you are processing. For instance:
Fields used in the form that triggered the request (under req.body)
Parameters used in the request URL (under req.params)
Session/cookie information (under req.session)
See here for more.
And in the function(err, account) callback, where exactly is it getting the err and account variables?
By convention in Node, callbacks pass any errors as the first parameter, and any non-error results from the second parameter onwards. So you'll typically see the first parameter called err. The structure of the err object is not completely standard, but it is normal to assume there will be a message field in the err object, and perhaps some error code.
In your example, you are handing that callback to, it seems, Mongoose, or some other database handling library. This library will try to execute a register function on the User object/model/schema. When it's done, if it encountered any errors, they'll come back to you on the err object. Else, you can expect the account object to hold details on the user account.
Also: you could name err and account whatever you want, of course.