Node Express Server Get not getting the first '?' in a query - node.js

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.

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();
};

How do I insert a newline in Node.js when using Heroku?

I'm trying to create a Node.js application on Heroku that will output 10 different ASCII faces (I already have the module needed for that). Using the Node tutorial on Heroku, I've set it up to output 10 faces. However, when I try to actually run the code, it puts all of the faces inline with each other. How should I try to make it so that the faces are outputted (if that's even a word) on their own lines?
My current index.js is as follows:
var express = require('express');
var app = express();
var cool = require('cool-ascii-faces');
app.set('port', (process.env.PORT || 5000));
app.get('/', function(request, response) {
var result = ''
var times = process.env.TIMES || 5
for (i=0; i < times; i++)
result += cool();
response.send(result);
});
app.listen(app.get('port'), function() {
console.log("Node app is running on port: " + app.get('port'))
})
I have a .env file already set up for Foreman to use (when testing locally) that contains the following:
TIMES=9
If you want to have a look at the output, head on over here.
TL;DR: How do I use newlines in Node?
I visited the site in question and did a View -> Source. There's no markup of any kind like HTML, BODY, etc. I assume that the browser then would interpret the output as HTML. This ought to work since we're using an HTML tag and a pair of PRE tags to indicate that if we see a hard return ('\n') then the browser should display it.
app.get('/', function(request, response) {
var result = '<html><pre>';
var times = process.env.TIMES || 5
for (i=0; i < times; i++)
result += cool() + '\n';
result += '</pre></html>';
response.send(result);
});
By default, the browser assumes that web servers send HTML.
HTML ignores newlines.
If you aren't sending HTML, you need to specify that by setting a different type:
response.header("Content-Type", "text/plain");
To actually send a newline, just concatenate '\n' to your string.

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));
}

Nested express app use does not work

When i am doing nested express apps, nested app use does not work
var app = express();
var localApp = express();
app.use('/pdf-exporter', PDFExporterModule());
function PDFExporterModule(app) {
localApp.use(function(req, res, next) {
//this code never execute !!!!!!
next();
});
localApp.get('/subpath/:userId', function() {...});
return localApp;
}
localApp doesn't have a value when you first call PDFExporterModule(). Move var localApp=express() up, or better yet, don't define local app outside of PDFExporterModule.
Also, it's good practice to leave all your var statements at the top. Variable hoisting makes localApp exists and is undefined right at the top of your script. It gets its value though where you have var localApp=express() below.

How to check express local variable exists when in script tag of jade?

I have a data variable sent to client-side, but it may not always be included as a variable in the express locals. If it doesn't exist, var data = !{JSON.stringify(data)}; returns var data = ; which causes a js error.
I've tried using conditionals prefixed with '-' but that doesn't seem to work.
script(type='text/javascript')
- if locals.data
var data = !{JSON.stringify(data)};
- else
var data = {};
How do I give it a default if locals.data is undefined?
Don't you hate it when you wrack your brain, then ask for help on SO, only to figure it out 5min later...
Looks like the following keeps the jade and javascript happy:
var data = !{ JSON.stringify(locals.data || '') };

Resources