TypeError: register.route(...).use is not a function - node.js

I'm using express.Router() whenever i try use method it gives the following error
TypeError: register.route(...).use is not a function
Code
/server/routes
const express = require('express');
const register = express.Router();
const account = require("../controller/AccountController");
const Middleware = require("../utils/middlewares");
register.route('/')
.post(Middleware.checkUser)
.post(account.user_register)
register.route('/verify/:token')
.get(Middleware.verifyEmail)
register.route('/resend/:email')
.use(Middleware.sendVerification)
module.exports = register;
Server.js
server.use('/register', register);
When i use a method like get there is no error. But i don't want to use any method since the middleware just sends an email

As stated in documentation, route all method is intended for route-specific middleware, it could be:
register.route('/resend/:email')
.all(Middleware.sendVerification)
If the route is expected to be requested with GET only and may not make sense for other verbs, it should be narrowed down to supported verbs:
register.route('/resend/:email')
.get(Middleware.sendVerification)
In this case sendVerification seems to be route handler and not a middleware. It's suitable to specify it only for get if /resend/ is expected to be requested with GET.

Related

express routing and path params

I have the following routing in app.js
app.use("/api/:phone/stuff", userRoutes);
In userRoutes, I have the following
userRoutes.get("/", userController.getStuff);
The client (Android app, retrofit) requests the following url: GET /api/+155555555/stuff, in userService I have getStuff method which is executed as expected, meaning it routes it well.
in a validation middleware, I see that req.originalUrl contains the url as expected but when viewing req.params, it is an empty object. I was expecting it to link the phone part of the url to :phone param so I will have req.params.phone.
I thought the problem was the + sign but it is urlencoded and even without it, it didn't work. What am I missing?
By default express router does not inherit parent router params
const userRoutes = express.Router({ mergeParams: true });
should do the trick
http://expressjs.com/en/4x/api.html#express.router

what happens in app.use(express.static) and app.use(require("cors")()) and what middlewares are

I started with express a few days ago.
I dont really understand what happens in:
const express = require("express")
const app = express()
app.use(express.static(path.join(), "public"))
app.use(require("cors")())
app.listen(3000, () => console.log("running"))
the first example worked for me but i dont really understand it.
and basiclly i dont understand what happens in app.use() and what middlewares are..
someone can help me pls?
i read many blogs and I didnt got it :(
The Background
There are several parts to explaining this. First, off app.use() expects a middleware function to be passed to it. That would be a function with a signature like this:
app.use(function(req, res, next) {
console.log(req.path); // log incoming request path
next(); // continue routing to other handlers
});
It accepts other combinations of parameters, including an initial path and you can pass multiple middleware functions too and it will chain them together, but the basics of your question is about a single middleware function as shown above. That middleware function gets three arguments req - the incoming request object, res - the outgoing response objet and next - a function to call if you want to continue routing or report an error.
The job of one of these middleware function is to use the input in the req object to do some kind of processing of that input (depending upon what the purpose of the middleware function is) and then do one of three things:
Send a response using something like res.send() in which case the request has been handled and a response has been sent and no further routing will be done.
Continue routing to further request handlers in the chain by calling next().
Abort routing and go to the Express error handler by calling next(err).
The express.static() Middleware
So, that's what is expected of a function passed to app.use(). Now, let's look at the two examples you ask about. Let's start with express.static():
app.use(express.static(path.join(), "public"))
First, this isn't proper use of express.static(). I'm not sure exactly what you intended, but I will assume you meant something like this:
app.use(express.static(path.join(__dirname, "public")));
In this case, express.static() takes some configuration information which is the resulting path from calling path.join(__dirname, "public") and uses that to create a custom middleware function. So, calling express.static(path.join(__dirname, "public")) returns a function that expects to be called with the three middleware arguments we previously discussed. It is logically identical to this:
const publicPath = path.join(__dirname, "public");
const myStaticMiddleware = express.static(publicPath);
app.use(myStaticMiddleware);
which is logically equivalent to this:
const publicPath = path.join(__dirname, "public");
const myStaticMiddleware = express.static(publicPath);
app.use(function(req, res, next) {
myStaticMiddleware(req, res, next);
});
Where the code has been broken down into separate steps just so you can see each step separately.
And, in case you didn't already know, the point of the express.static() middleware is to serve static files from a designated directory if an incoming request matches a filename in that designated directory exactly and has an appropriate file type.
The cors Middleware
For your second example:
app.use(require("cors")())
Let's again break that down to the individual steps:
const cors = require("cors"); // load cors module
const corsMiddleware = cors(); // create cors middleware function
app.use(corsMiddleware); // register middleware with Express server
Which can be expanded to:
const cors = require("cors");
const corsMiddleware = cors();
app.use(function(req, res, next) {
corsMiddleware(req, res, next);
});
Just to show you that corsMiddleware is called with these three arguments.
The purpose of this particular middleware is to help configure a response to this request so that cross origin requests will be accepted.

How do I access URL parameter after i've routed my express app to another file?

My main express server is called app.js in Node.js.
app.use("/login", require(./routes/login));
app.use("/:id", require("./routes/users"));
When I try to access the URL parameter, it returns undefined.
I tried logging req.params:
const express = require('express');
const router = express.Router();
router.get('/dashboard', (req, res) => {
res.send(`Current Ornament Status and Data for ${req.params}`);
});
module.exports = router;
It gives me an empty array.
I suppose that it the parameter is inaccessible in another file after routing. Could you suggest a workaround?
I think you're missing some fundamental bits about express.js routing for this to make sense.
The requires line means it is loading another piece of code. So you need to show us that too.
The :id thing requires a longer explanation.
Let's say I want the server to process the URL /finduser/23
Where 23 can vary, could be just about any number. I am NOT going to write 99 different versions of router.get, right?
router.get("/finduser/1",...
router.get("/finduser/2",...
router.get("/finduser/3",...
No, what we do is turn that into a parameter
router.get("/finduser/:id",...
Then whatever number we pass turns into req.params.id, assume router passes req,res
EX: If we pass URL /finderuser/15, then req.params.id = 15
If you just pass /finduser then req.params.id gets NOTHING.
Full details are available here
http://expressjs.com/en/guide/routing.html#route-parameters
Your example:
router.get('/dashboard', (req, res)
Doesn't have ANY parameters. so req.params.id has nothing.

How to check the content of Koa's ctx.query?

For a Koa-based API server, I want to check what parameters the URL query contains.
My setup looks as simple as this:
const Koa = require('koa')
const app = new Koa()
const Router = require('koa-router')
router = new Router()
router.get('/', ctx => {
console.log(ctx.query)
})
app.use(router.routes())
app.use(router.allowedMethods())
app.listen(3000)
It seems that ctx.query has a structure like an object but doesn't work as one.
Methods like ctx.query.hasOwnProperty() or ctx.query.toString() result in an error saying that it is not a function.
Though, Object.keys(ctx.query) gives an array of the keys—which is confusing to me because it apparently is an object and should have above methods.
What is ctx.query exactly? How can I make the failing methods from above working?
ctx.query is the return from Node.js' querystring.parse() method. From the documentation:
The object returned by the querystring.parse() method does not
prototypically inherit from the JavaScript Object. This means that
typical Object methods such as obj.toString(), obj.hasOwnProperty(),
and others are not defined and will not work.
You can check Koa's request implementation.

Where are get, post methods defined in ExpressJS?

I'm unable to find the code of get or post methods. I haven't found them in expressjs lib folder, so it's probably that they are present in one of the js files the Router requires.
var express = require('express');
var router = express.Router();
var Blah = require('../modules/Blah');
router.post('/', function(req, res, next) {
Blah.foo(req, res);
});
I need it to find out where the next parameter is passed to that callback function above, because it has to be done by ExpressJS framework under the hood.
Express uses the methods module to dynamically attach http verbs to the router :
lib/router/index.js :
// create Router#VERB functions
methods.concat('all').forEach(function(method){
  proto[method] = function(path){
    var route = this.route(path)
    route[method].apply(route, slice.call(arguments, 1));
    return this;
  };
});
See the answer by KeatsPeeks for more details. Here are some links to specific parts of the source code that might be helpful:
get and post methods are defined in the methods module here:
https://github.com/jshttp/methods/blob/master/index.js#L14-L15
Here in lib/applciation.js the .METHOD calls for them are delegated to router.METHOD:
https://github.com/strongloop/express/blob/master/lib/application.js#L471-L484
The rest is in lib/router/index.js:
https://github.com/strongloop/express/blob/master/lib/router/index.js#L506-L513
And in lib/router/route.js - search for "methods" in:
https://github.com/strongloop/express/blob/master/lib/router/route.js

Resources