I am new in Express so I would like some help. I need to create a router to get some values from an endpoint that will be as follow (I can't modify the endpoint, it is a requirement)
../house/1/us/ny&zipcode=12345
I tried
router.get("/:id/:country/:state")
and I am getting the id, country, and state with req.params
I get
id=1
country=us
and for the value of the state, I get "ny&zipcode=12345" but I actually want to get both
state=ny zipcode=12345
I tried with req.query but it doesn't work or perhaps I am using it incorrectly Any suggestion? Thanks in advance
The first issue (I guess?) in the code I see is that you're using & instead of ? to start the query parameters; we use & to separate key value pairs (like foo=bar&baz=hello). So, you might want to check that once.
If you change the & to a ?, you can access it using req.query.<objectName>.
I also just your edit, and for that to work we can work with /house/:id/:country/:stateAndZip we need to make a few changes.
I would probably use this approach:
const { stateAndZip } = req.params;
const [ state, zipCode ] = stateAndZip.split( '&' );
// Here, state contains 'ny' and `zipCode` is of the work `zipcode=XXXXX`.
const [ , formattedZipCode ] = zipCode.split( '=' ); // Or use https://nodejs.org/api/querystring.html
// formattedZipCode is XXXXX.
There are a few problems with this solution; the first one being that this assumes the zipcode is the first argument after &. If you want a more generic way of doing it, please let me know.
Taking the solution from above and assuming we have an unordered list where zipcode can be anywhere, we can do the following:
const qs = require( 'querystring' );
const { stateAndZip } = req.params;
const [ state, queryParams ] = stateAndZip.split( '&' );
const decodedQueryParams = qs.parse( queryParams );
// decodedQueryParams will be an object with the property `zipcode`.
One issue here is that we may have an ampersand (&) in the URL itself, you can take this solution a step further by assuming that all state names in their abbreviated form are only 2 characters and read till the &, and parse out the remaining string using querystring.
As mentioned, your requirement is a bit strange. However, expressjs router's path definition is very elastic (look for Route paths section under official documentation). You can define a route with your pattern like this:
/:id/:country/:state&zipcode=:zipcode
Fast testing
Use Express Route Tester, put /house/:id/:country/:state&zipcode=:zipcode in Route field and /house/1/us/ny&zipcode=12345 in Path field.
Full example
import * as express from 'express';
const express = require("express");
const app = express();
const houseRouter = express.Router();
houseRouter.get("/:id/:country/:state&zipcode=:zipcode", (req) => {
console.log(req.params);
});
app.use('/house', houseRouter);
app.listen(3000);
To test, call http://localhost:3000/house/1/us/ny&zipcode=12345 from postman/browser.
Console would log:
{ id: '1', country: 'us', state: 'ny', zipcode: '12345' }
The endpoint should be /house/1/us/ny?zipcode=12345 and then req.query.zipcode will have the zipcode value. ? instead of &.
When /house/1/us/ny&zipcode=12345 is used, req.params consider ny&zipcode=12345 as the value for the key state. ? ends the endpoint and begins the query parameters.