Express js optional parameter - node.js

I'm looking to add an optional parameter to an express route where var1 has to be set but var 2 can be ommited (/test/0 and /test/0/0 should both work).
I could create another rule, or juste evaluate the string "test/0/0" but I'm wondering if there is no other way.
app.get('/test/:var1/:var2', function(req, res){
// DO SOMETHING
});
Thanks !

app.get('/test/:var1/:var2*?',function(req,res)
{
if(!req.params.var2){
// do something when there is no optionalParam
}
res.json({ var: req.params.var1,
var2: req.params.var2 });
});
just call
http://127.0.0.1:8080/test/44
output
{"var":"44"}
incase of passing both
{"var":"44","var2":"77"}

Related

Node Js API : where the undefined comes from?

I write this code to get the array from url. this is the url : http://localhost:3000/main?a=aaa.jpg&a=bbb.jpg
And here is the code :
//Define module
var express = require('express');
var app = express();
const { exec } = require('child_process');
//extract function
function extract (req,res,next){
res.write(`filename : ${req.query.a}`); //kt page
console.log(req.query.a);//kt terminal
next();
};
//main function
function main (req,res,next){
res.write('\nkuor dok \n');
res.end();
};
app.use(extract);
app.get('/main',main);
app.listen(3000);
This is the output in terminal.
Array(2) ["aaa.jpg", "bbb.jpg"]
undefined
The question is where the undefined comes from? It affected everything i need to do. The array is perfectly fine. But suddenly undefined comes out. Can anyone help me. Thank you in advance.
I tried the code you provided above and i got only the array in the terminal
[ 'aaa.jpg', 'bbb.jpg' ]
When i tried the url in the browser i got
filename : aaa.jpg,bbb.jpg
kuor dok
as the output. i didn't get any undefined
I see that you are trying to define extract function as a middleware. It will be executed for every request
try to comment app.get:
app.use(extract);
//app.get('/main', main);
app.listen(3000);
Then try to make the request
GET: http://localhost:3000/main?a=aaa.jpg&a=bbb.jpg
you will get
[ 'aaa.jpg', 'bbb.jpg' ]
You are handling the request twice. First by the global middleware, the second time by app.get() that calls also the middleware extract before main
As I see app.get don't handle your query params and you got undefined due to an empty object try to log: req.query intead of req.query.q
function extract(req, res, next) {
res.write(`filename : ${req.query.a}`); //kt page
console.log(req.query); //kt terminal
next();
};

Node Express Server Get not getting the first '?' in a query

I am trying to make a get call to my node server using the following parameters
http://localhost:8080/products/?a=13214?b=awedf
I am getting the error: Cannot GET /products/?a=13214?b=awedf
When I remove the '?' before the letter 'a', I get the following query:
{ b: 'awedf' }
I want to be able to add the '?' and get the following query or something similar that gives me the following array:
{ a:13214, b: 'awedf' }
Here is the code I have:
var express = require('express'),
app = express();
var timeout = 0;
app.use(express.static(__dirname, '/'));
app.get('/products/:siteId', function(req, res) {
console.log(req.query);
res.json(products);
});
app.listen(8080);
console.log('Express listening on http://localhost:8080/');
var products = [
{"Product":"Product A"}
,{"Product":"Product B"}
];
EDIT:
I fixed it by changing the query parameters:
http://localhost:8080/product?a=13214&b=awedf
Instead of second ? add &. Parameters are separated with ampersand. Question mark indicates the beginning of query string
Also you don't need :siteId in the path. If you want to use :siteId, then your url would look like /products/1234?b=abc
req.params.siteId === 1234 and req.query.b === 'abc'
So you should replace the ? before b with & like this: http://localhost:8080/products/?a=13214&b=awedf
EDIT: Since you cannot modify the parameters and you already have /:siteId then you should be able to access the value for a like this: req.params.siteId.

How to get list of all routes I am using in restify server

I have a app designed as follows;
//server.js =====================================================
var restify = require('restify'),
route1 = require('./routes/route1),
route2 = require('./routes/route2),
....
....
....
var server = restify.createServer({
name: 'xyz_server'
});
route1(server);
route2(server);
Now each route file looks like belwo
//route1.js =====================================================
module.exports = function(server) {
server.get('/someRoute',function(req,res,next){
//.. do something
});
server.get('/anotherRoute',function(req,res,next){
//..something else
});
};
Now the issue is tht we have dozen's of route files and hundreds of routes in total.
There are multiple developers working on this project and several routes are being added daily.
Is there a function in restify gives me a list of all routes in the system ?
What i am looking for is something like:
server.listAllRoutes();
Is anyone aware of this ?
Try something like this
function listAllRoutes(server){
console.log('GET paths:');
server.router.routes.GET.forEach(
function(value){console.log(value.spec.path);}
);
console.log('PUT paths:');
server.router.routes.PUT.forEach(
function(value){console.log(value.spec.path);}
);
}
listAllRoutes(server);
This should list all GET and PUT paths, adding POST and DELETE should be easy :)
2019 update: server.router.routes is no longer available instead we have server.router.getRoutes() which returns a Map. So we can log all the routes using:
function listAllRoutes(server) {
Object.values(server.router.getRoutes()).forEach(value =>
console.log(
`ENDPOINT REGISTERED :: ${value.method} :: ${server.url}${value.path}`
)
);
}
http://restify.com/docs/server-api/#server
There is a router.getRoutes() method, but it returns an object which is not the best to work with for listing things. You could fiddle around with that to turn it into an array with the shape that you like.
Alternatively, you can access all the routes as an array and then map them, even better if you use a lib like better-console to give you console.table in node. The following is working nicely for me in restify#8.3.0:
import console from 'better-console';
function listRoutes(server) {
const { routes } = server.router._registry._findMyWay; // beware these are probably meant to be private APIs, they could be subject to change
const mapped = routes.map(({ method, path }) => ({ method, path }));
console.table(mapped.sort((a, b) => a.method > b.method));
}

node js (with ejs view engine) give undefined variable on the view

I've been working on this for a few hours now but still can't get anywhere. I have a view that tries to create a geojson file on the fly and return it to the node view as a variable. The variable is not empty before it hits the res.render line but when it the view gets loaded, the result is always undefined.
app.get('mymap', function(req, res, next){
var featureCollection= {
type : 'FeatureCollection',
features : new Array()
};
Shapes.find({'id' : 778899}, function(err, data){
data.forEach(function(d){
collection.features.push(d);
});
res.render('mymap.ejs', { geojson: featureCollection});
});
});
this is where i call to see if there's something on the view
var mymap = '<%- geojson%>';
alert('Current values ' + mymap.type);
Not really sure what's wrong.. I even tried to just make up a variable with multiple properties, eg:
var test = { place: 'Here and There', size : 5555 }
res.render ('mymap.ejs', { geojson: test });
Still nothing happens.
Well, you had a typo in your code:
var mymap = '<%- geojson%>';
It should be:
var mymap = '<%= geojson %>';
More precisely, if you want to read a Javascript Object from server-side, I suggest to pass it as a JSON string:
var mymap = JSON.parse('<%= JSON.stringify(geojson) %>');

formidable doesnt work with express

Before you wast any time : please note that this is a reference question , just in case some one needed it. but please feel free to correct me :)
so , im trying to use formidable (i know that it's so similar to bodyParser and that i should be using body parser instead ! ) with express . the problem that it doesnt work at all .
here is simple part of my code (relevant part )
form.on('progress', function (bytesReceived, bytesExpected) {
console.log(bytesExpected);
console.log('progress ');
if (bytesReceived > options.maxPostSize) {
console.log('bla ');
req.connection.destroy();
}
}).on('end', finish).parse(req,function(err, fields, files) {
console.log(files);
});
now if i try to console.log -> err , fields , or files it doesnt work .
an the only event that is being emitted is progress .
if you use app.use(express.bodyParser())
is equivalent to:
app.use(express.json());
app.use(express.urlencoded());
app.use(express.multipart());
the multipart use formidable, so events doesn't trigger,you can remove app.use(express.multipart()); then you can use formidable object.
The problem is caused by the parse function . To solve this you need to not use the bodyParser .
So let's assume that i have a route /files which only recives a post request then you need to disable the bodyParser just for that route like so :
app.use(function(req,res,next){
// important .. this will skip body parser to avoide issues with formidable
if((req.path == '/file' ||req.path == '/file/') &&req.method === 'POST'){
// GET , PUT , DELETE ,etc... will have bodyParser ^^^^^^^^^^^^^^^^^^^^^
return next();
}
express.bodyParser(req,res,next);
next();
});

Resources