Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 5 years ago.
Improve this question
Hi Everyone I am newbie to Express + NodeJS. I come from Java and trying to get caught up on Node now so please be gentle if I ask some basic questions (I have spent the last 2 days catching up on this stuff)
My questions are around documentation.
So when I look through some of the examples present on Express site I see the following
app.get('/users/:id?', function(req, res, next){
......
});
and sometimes
app.get('/users/:id?', function(req, res){
......
});
where is the documentation for me to determine how many paramaters go into the function?? first theres was req, res and next but then it had req and res.
Second question: where is the documentation for what is available on the request and response objects along with other method that are available as part of the framework?
I looked up the documenation here http://expressjs.com/guide.html#req.header() but I can't imagine this is entire doc because i notice methods being used on examples that are not present on this documentation.
Can someone point me to the most commonly used docs for express + nodeJS development? If you can list all the links here I would be very grateful!
First question: You need to slow down a minute. Do you have any experience with another language besides Java? Javascript does not have method signatures in the way you know from Java. Here is a quick example:
function foo(bar, baz, qux) {
var result = bar + baz;
if(qux) {
result += qux;
}
return result;
}
foo(1, 2);
// => 3
foo(1, 2, 3);
// => 6
It's a contrived example, but it shows that you can declare a function which takes 3 arguments, and only use two of them. In fact, it could use arguments directly and accept even more arguments than specified in the function declaration!
function bar(foo) {
if(arguments.length > 1) {
var baz = arguments[1];
return foo + baz;
}
return foo;
}
bar(2);
// => 2
bar(2, 4);
// => 6
Anyway, in short, your route handler function(req, res, next) {} will always be called with req, res, and next -- but it just might be the case that you don't need next (because you won't ever pass on control, perhaps), so you omit it (it will still be there, in your arguments object, just not scoped as next). Some feel this is sloppy, others that it's succinct.
Second question: Here is node.js docs, http.ServerRequest, http.ServerResponse. You already know the Express guide.
JavaScript is kind of lax about the number of parameters a function takes. If a function takes two parameters, you can still pass it five arguments — the first two you pass will go in the named parameters, and the rest will only be available through the arguments object. (Similarly, if you write a function that takes three arguments, a caller can still pass only two and the third will have the value undefined.)
So basically, the function will always get three arguments, but a lot of times you have no intention of using the next continuation, so you can just leave it off and JavaScript will silently swallow it.
As for documentation, that guide is the official documentation for Express. The docs for Node.js are at nodejs.org. Express's modules are generally based off their vanilla Node equivalents (e.g. the server is based off Node's http.Server).
Related
I am trying to understand the node.js documentation specifically for the https.get() method. https://nodejs.org/dist/latest-v8.x/docs/api/https.html#https_https_get_options_callback
What is unclear to me is the callback. The example in the document indicates the callback can take a res (response) object as its parameter but I am unsure if this is the only parameter it can take or more importantly where I can find the definition of the res object so I can know what properties and methods I can access on this object.
Is there a straightforward way to identify this?
I have read this thread: Trying to understand nodejs documentation. How to discover callback parameters and the answers seem to suggest that if there is a non-error argument that a callback can take it will be documented, but I am assuming that answer is outdated.
I've run into the same issue with many Node/NPM packages. Documentation sometimes does not describe the parameters well.
So, welcome to JavaScript in 2018! It's gotten a lot better, though, to be honest.
My go-to method is to try the methods and dump the information myself.
Try a console.dir(res) in your callback:
https.get('https://encrypted.google.com/', (res) => {
console.dir(res);
});
Alternatively, you can set a breakpoint in the callback and inspect it yourself. You can then probe the arguments object* to see what else, if anything, was passed as an argument, or do another console dump:
https.get('https://encrypted.google.com/', function (res) {
console.dir("args:", arguments);
console.dir("res:", res);
});
EDIT: Wait, apparently the arguments variable is not available to arrow functions, fixed the second example.
*From MDN:
The arguments object is not an Array. It is similar to an Array, but
does not have any Array properties except length.
From your link https://nodejs.org/dist/latest-v8.x/docs/api/https.html#https_https_get_options_callback, you can see that it works like the http version :
Like http.get() but for HTTPS.
With http.get() clickable.
On that page (https://nodejs.org/dist/latest-v8.x/docs/api/http.html#http_http_get_options_callback), we can see this :
The callback is invoked with a single argument that is an instance of http.IncomingMessage
With http.IncomingMessage clickable, linking this page :
https://nodejs.org/dist/latest-v8.x/docs/api/http.html#http_class_http_incomingmessage
I agree the Node documentation is not very clear about the callbacks in general, and that is a shame. You can still use IDEs with good intellisense (and JSDoc to identify the type of the function parameters), like VSCode.
Or you can use a debugger, always works :)
Edit: If you want to see all the parameters sent to a function, you can use the spread syntax like this :
function foo(...params) {
// Here params is an array containing all the parameters that were sent to the function
}
If you want the absolute truth, you can look at the implementation. Though that's fairly time consuming.
If you find that the documentation is wrong, or in this case could be improved by adding a sentence about the callback parameter to https.get(), please open an issue, or, better yet, a pull request. This is where the change needs to be made:
https://github.com/nodejs/node/blob/67790962daccb5ff19c977119d7231cbe175c206/doc/api/https.md
I am completely lost on this one. I have a simple app that asks 6 questions to a user. Each question and the answers available are shown on a dynamically generated view for a particular questions route. I want to set up a time that works as follows: When question 1 shows, the user has 5 minutes to answer all 6 questions. The timer would clear once the POST for question 6 occurs.
The basis for the GET/POST code is as follows (using the ejs model):
app.get('/survey/:question_number?', restrict, routes.survey);
app.post('/survey/:question_number', function(req, res) {
//question code
}
Here is the export route code:
exports.survey = function(req, res) {
//Question logic to pass to the render
res.render('question', {
info : info
});
}
For the html, it simply uses the passed "info" to generate the questions and answers and then uses a standard form method=post to send the answer selected back to the app.post.
Can anyone recommend a good method to accomplish this that is not overly complex? Thanks!
You should probably use sessions for this task. After the first question is requested you set a session variable, that will indicate the time, when all questions must be answered. After that you just compare this variable value with a current time of a request. I guess it's one of the most simplest approaches to solve your task.
So, I'm going through the Node.js learnyounode tutorial (which is pretty fun), but I'm no stranger to javascript. One of the requests is to have the user write a program that accepts a directory and a file extension as arguments, and then proceeds to ls the files which match the given extension.
In checking my arguments in various places where data is passed through functions, I cannot get Node.js to allow me to pass additional arguments to a callback function for a built-in function.
For example, I can run the following snippet, pass an err, path, and extension, and would like to see the all the passed arguments, but I only see err and data in the arguments object while the "ext" variable is ignored.
var fs = require("fs"), path = require("path")
var dir = process.argv[2], ext = process.argv[3];
fs.readdir(dir, function (err, data, ext) {
console.log(arguments);
});
The reason for wanting this functionality is to avoid breaking the function scope to retrieve the value of ext.
I can do this type of thing with custom functions all day, but the built-in functions are a little less forgiving.
Thanks,
Bob
The easiest way is to just use the built-in path.extname() function on each entry name:
fs.readdir(dir, function(err, entries) {
if (err) throw err;
for (var i = 0; i < entries.length; ++i) {
if (path.extname(entries[i]) === ext)
console.log(entries[i]);
}
});
Talked to the node.js people in irc, turns out the way javascript works such a method to keep scope in bounds is not necessary. Node.js, by default, puts modules in their own closures, so the variables can be accessed outside the function and not interfere with global namespace.
Found this answer on node js and variable scope which probably best matches my situation, but didn't know it's what I needed when I posted my question.
Also found some nice closure examples on Mozilla.
On a personal note I thought I knew javascript a little better than this, and I hope this answer helps people who are coming from C / PHP backgrounds into node.js
I'm currently building a small express powered node app to power a RESTful API exposing data from a node module I wrote. One of the functions in the module takes three arguments, but I want to allow the usage of the API by specifying just one, two, the other two or all three arguments.
So even starting to write the routes like this already feels ridiculous.
app.get('/api/monitor/:stop/:numresults', apiController.monitorNum);
app.get('/api/monitor/:stop/:timeoffset', apiController.monitorOff);
app.get('/api/monitor/:stop', apiController.monitor);
Especially since I don't know how to specify the difference between the first two, as numresults and timeoffset are both just integers.
What would a best practice in this situation look like?
The first problem you face is that you have identical routes, which are not possible if you're using express (I'm assuming that's what you're using). Instead you probably want one route and utilise the query object instead:
app.get('/api/monitor/:stop/', function (req, res, next) {
var stop = req.params.stop,
numResults = req.query.numResults,
timeOffset = req.query.timeOffset;
yourFunc(stop, numResults, timeOffset);
});
That way you can call the api with the following url: http://example.com/api/monitor/somethingAboutStop/?numResults=1&timeOffset=2. It looks like the stop parameter can also be moved to the query object but it's up to you.
You can use a catchall route then parse it yourself.
Example:
app.get('/api/monitor/*', apiController.monitor);
Then in apiController.monitor you can parse the url further:
exports.monitor = function(req, res) {
var parts = req.url.split('/');
console.log(parts); // [ '', 'api', 'monitor', '32', 'time' ]
console.log(parts.length); // 5
res.end();
};
So, hit the /api/monitor/32/time, and you get that array above. Hit it with /api/monitor/something/very/long/which/you/can/parse and you can see where each of your params go.
Or you can help yourself, like /api/monitor/page/32/offset/24/maxresults/14/limit/11/filter/by-user
Though, as Deif has told you already, you usually do pagination with query parameters, maxResults & page being your usual params.
I'm new to javascript, and jumped right into node.js. I've read a lot of theory, and began well with the practical side (I'm writing an API for a mobile app), but I have one basic problem, which has lead me to middleware. I've successfully implemented a middleware function, but I would like to know if the use I'm giving the idea of middleware is OK, and also resolve the original problem which brought me to middleware. My question is two-fold, it's as follows:
1) From what I could gather, the idea of using middleware is repeating a process before actually processing the request. I've used it for token verification, as follows:
Only one of my urls doesn't receive a token parameter, so
app.js
app.get('/settings', auth.validateToken, auth.settings);
auth.js
function validateToken(req, res, next){ //code };
In validateToken, my code checks the token, then calls next() if everything is OK, or modifies res as json to return a specific error code.
My questions regarding this are: a) Is this a correct use of middleware? b) is there a [correct] way of passing a value onto the next function? Instead of calling next only if everything is OK, is there a [correct] way of calling next either way, and knowing from inside the next function (whichever it is), if the middleware was succesful or not? If there is, would this be a proper use of middleware? This precise point brings me to my original problem, and part two of this question, which is encapsulating functions:
THIS PART WAS FIXED, SEE MY SECOND COMMENT.
2) I discovered middleware trying to simply encapsulate validateToken, and be able to call it from inside the functions that the get handlers point to, for example auth.settings.
I'm used to common, sequential programming, and not in javascript, and haven't for the life of me been able to understand how to do this, taking into account the event-based nature of node.js.
What I want to do right now is write a function which simply verifies the user and password. I have it perfectly written inside a particular handler, but was about to copy-paste it to another one, so I stopped. I want to do things the right way from scratch, and understand node.js. One of the specific problems I've been having, is that the error code I have to return when user and password don't match are different depending on the parent function, so I would need this function to be able to tell the callback function "hey, the password and user don't match", so from the parent function I can respond with the correct message.
I think what I actually want is to write an asynchronous function I can call from inside another one.
I hope I've been clear, I've been trying to solve this on my own, but I can't quite finish wrapping my head around what my actual problem is, I'm guessing it's due to my recent introduction to node.js and JS.
Thanks in advance! Jennifer.
1) There is res.locals object (http://expressjs.com/api.html#res.locals) designed to store data local to the request and to pass them from one middleware to another. After request is processed this object is disposed of. If you want to store data within the session you can use req.session.
2) If I understand your question, you want a function asynchronously passing the response to the caller. You can do it in the same way most node's functions are designed.
You define a function in this way:
function doSomething(parameters, callback) {
// ... do something
// if (errorConddition()) err = errorCode();
if (callback) callback(err, result)
}
And the caller instead of using the return value of the function passes callback to this function:
function caller(req, res, next) {
//...
doSomething(params, function(err, result) {
if (! err && result) {
// do something with the result
next();
} else {
// do something else
next();
// or even res.redirect('/error');
}
});
}
If you find yourself writing similar callback functions you should define them as function and just pass the function as parameter:
//...
doSomething(param, processIt);
function processIt(err, result) {
// ...
}
What keeps you confused, probably, is that you don't treat functions as values yet, which is a very specific to JavaScript (not counting for languages that are little used).
In validateToken, my code checks the token, then calls next() if everything is OK, or modifies res as json to return a specific error code.
a) Is this a correct use of middleware?
b) is there a [correct] way of passing a value onto the next function?
Yes that is the correct way of using middleware, although depending on the response message type and specifications you could use the built in error handling of connect. That is in this example generate a 401 status code by calling next({status:401,stack:'Unauthorized'});
The middleware system is designed to handle the request by going through a series of functions until one function replies to the request. This is why the next function only takes one argument which is error
-> if an error object is passed to the next function then it will be used to create a response and no further middleware will be processed. The manner in which error response is created is as follows
// default to 500
if (res.statusCode < 400) res.statusCode = 500;
debug('default %s', res.statusCode);
// respect err.status
if (err.status) res.statusCode = err.status;
// production gets a basic error message
var msg = 'production' == env
? http.STATUS_CODES[res.statusCode]
: err.stack || err.toString();
-> to pass values down the middleware stack modifying the request object is the best method. This ensures that all processing is bound to that specific request and since the request object goes through every middleware function it is a good way to pass information down the stack.