Why does this next() function print its argument in console?

Viewed 302

I am a tyro in node and express, learning the things. I was reading Express's documentation at this link: https://expressjs.com/en/guide/routing.html and in the Route Handlers section of this page, it says:

You can provide multiple callback functions that behave like middleware to handle a request. The only exception is that these callbacks might invoke next('route') to bypass the remaining route callbacks.

The examples given on this page doesn't contain any next() with arguments in it.

I tried implementing it and passing some path as an argument in this function but it behaves strangely and prints that argument in the console and also sends it to the browser.
Below is my code:

const express = require('express');
const port = 8000;
const app = express();

app.get('/', (req, res, next) => {
    console.log("I am the first one");
    next('/demo');
}, function(req, res, next){
    console.log("I am the second one");
});

app.get('/demo', (req, res) => {
    console.log("Good!");
});

app.listen(port, (err) => {
    if(err){
        console.log("ERROS: ",err);
    }
    console.log("Express server is runnig on port: ",port);
});

In the browser, I typed http://localhost:8000/
The output in console is:

I am the first one
/demo

the next('/demo') function call doesn't cause /demo route handler to run.

Where am I going wrong?
Am I getting it right?
Actually I am not able to understand how this argument thing works with the next() function.

Since the documentation page does not have any example with arguments in function, Can anyone please explain how this next() function work with arguments through an example?

Thanks in advance for any help you are able to provide

2 Answers

I did some deep diving here because it seemed interesting to me and then I realized it's just the error being returned. Let me explain.

Basically next() which is a expressjs specific functionality is used to pass over the control to next functional unit. It doesn't expect parameters of string, barring one (given below - after the error piece). That even in a case when you initialize it properly.

Here is the output in the network tab once you load the page, please check.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>/demo</pre>
</body>
</html>

NOTE: next('route') will work only in middleware functions that were loaded by using the app.METHOD() or router.METHOD() functions.

You cannot call another router the way you are doing at the moment, http will have one response for one request to close the channel. However you can do something like.

app.get('/', (req, res, next) => {
    console.log("I am the first one");
    next();
}, function(req, res, next){
    console.log("I am the second one");
    next();
});
app.get('/', (req, res, next) => {
    console.log("I am the third one");
    next();
}, function(req, res, next){
    console.log("I am the fourth one");
});

Here middleware works it's magic and matches whatever identical route parameter is and goes on to execute it all.

The next() function in

app.get('/', (req,...

used to call the next callback in the same route

...
function(req, res, next){
    console.log("I am the second one");
});

Once you remove the /demo from the next('/demo'), you will notice "I am the second one" in the console. NOTE: next() only passes the control to the next middleware in the same route.

app.get('/', (req, res, next)=>{ 
    // E.g. purpose of this middleware is to print request method
    console.log('Request method:', req.method)
    next() // this code passes the control to the next callback which is below
}, (req, res) => {
    console.log('End of route')
    res.send('OK')
}

It does not engage the app's route. In order to go to another route, you have to send another HTTP request. Hope this helps!

UPDATE Here's the scenario where next('route') does something, this only works if 2 routes are of the same URI and http method.

const express = require('express')
const app = express();

function middleware1(req, res, next){
  console.log('Middleware #1')
  next('route') // ends current callback chain, moves to the next route
}

app.get('/', middleware1, (req, res, next)=>{
  console.log('Second middleware') // this callback is not executed
  res.send('OK')
})

app.get('/', (req, res)=>{
  console.log('Test') // the callback in this route gets called
  res.send('2nd get / OK')
})

app.listen(3000, () => {
  console.log('Server @', 3000)
})

I think this implementation of route is seldom being put into practice because personally I feel that it is tedious to follow (having 2 routes with the same uri and http method). Nonetheless it is good to learn something from Gandalf the White and this.

Related