简体   繁体   中英

How to handle null URL parameters with Express.js

I'm working on an assignment for my web services class and can't figure out how to handle a null URL parameter. Here is my code:

    app.get('/nachos/:x/:cheese/:tomatoes/:salsa/:hotsauce', (req, res) => {
        var x = parseInt(req.params['x'])
        var cheese = (req.params['cheese'])
        var tomatoes = (req.params['tomatoes'])
        var salsa = (req.params['salsa'])
        var hotsauce = (req.params['hotsauce'])

        res.send('You ordered ' + x + ' nacho(s) with ' + cheese + ', ' + tomatoes + ', ' + salsa + ', ' 
        + hotsauce + '.')})

This code works fine with all parameters filled. But how do I handle a null parameter if I don't want, for example, salsa and type in the url localhost:port/nachos/1/cheese/tomatoes/hotsauce

If I'm reading correctly the question is:

How do I handle a null parameter if I don't want, for example, salsa and type in the url localhost:port/nachos/1/cheese/tomatoes/hotsauce

You won't get null it simply won't match the route.

You can make params optional like:

app.get('/nachos/:x?/:cheese?/:tomatoes?/:salsa?/:hotsauce?', (req, res) => {

or add routes to match, which could get out of hand.

app.get([
    //...
    '/nachos/:x/:cheese/:tomatoes',
    '/nachos/:x/:cheese/:tomatoes/:hotsauce',
    '/nachos/:x/:cheese/:tomatoes/:salsa/:hotsauce',
    //...
], (req, res) => {

You don't really do optional arguments in a route definition that looks like this:

/nachos/:x/:cheese/:tomatoes/:salsa/:hotsauce

because in order for the route to match, every one of the parameters must be present and for req.params to contain the right option, they must all be in the correct order. If these are variations, some of which are entirely optional, then matching them the way you were is just not the proper URL design and matching a varying URL like that in Express will be a bit of a pain.

The simplest way I can think of is to just put the optional ingredients in a query string as in:

 /nachos/2?cheese=yes&tomatoes=yes&salsa=yes&hotsauce=yes

Then, you just match the route: /nachos/:x as the only required options for the URL and everything else can be optionally specified in the querystring and you can write your code so that it defaults to "no" if the option is not present. So, an order without hotsauce could be either of these:

 /nachos/2?cheese=yes&tomatoes=yes&salsa=yes&hotsauce=no
 /nachos/2?cheese=yes&tomatoes=yes&salsa=yes

An order without hotsauce or salsa could just be this:

 /nachos/2?cheese=yes&tomatoes=yes

Then, your request handler would look like this:

const orderOptions = ["cheese", "tomatoes", "salsa", "hotsauce"];

app.get('/nachos/:x', (req, res) => {
    console.log(req.query);

    let text = orderOptions.map(item => {
       return req.query[item] === "yes" ? item : null;
    }).filter(item => !!item).join(", ");

    res.send(`You ordered ${req.params.x} nacho(s) with ${text}.`);
});

I should mention that if this request is actually specifying an order, then it should probably be a POST, not a GET and the options should be in the body of the POST and they would take the same form as the querystring, probably encoded just like application/x-www-form-urlencoded from form POSTs.

Passing parameters this way request to the API user to send the parameters in the correct order. To handle the case you want (an ingredient missing), you would need to create another route to handle it. But you can do this in another way, like passing the parameters as query strings or even sending them on the request body (for non-GET routers preferably).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM