The Problem occurs while sending GET or any request with parameters in the URL.
for example my
index.js
const express = require("express");
const bodyParser = require("body-parser");
const app = express();
app.use(bodyParser.urlencoded({ extended: true }));
app.get("/:name", function (req, res) {
let name = req.params.name;
console.log("Hello " + name + " from /:name");
res.send("Hello " + name + " from /:name");
});
app.get("/", function (req, res) {
console.log("Hello world from /");
res.send("Hello world from /");
});
app.listen(3000, () => {
console.log("Server is running on port " + 3000)
});
For http://localhost:3000/ it's working perfectly fine.
the Problem is occurring when we try to hit /:name route
when we use URL http://localhost:3000/?name=NODE it is going to the same route as above. in /
But the crazy part is when we put http://localhost:3000/NODE which is simply a new different route that is not implemented.
It is getting the response from :/name which doesn't make any sense.
is it a BUG or I am doing something wrong or is it something new I am not aware of?
I am currently using Windows11,
this problem also occurs in my friend's PC who uses Ubuntu
When you define route as
/:name
That's called path parameter and it's used like this :
GET /yourname
And that's why this works :
GET /NODE
What you"re using to call the endpoint (?name=xxx) is called query parameter, you can get that name from '/' endpoint like this :
let name = req.query.name;
I think you're almost there, but /:name does not match /?name=, but it does match /NODE.
This is exactly what's expected to happen. If this surprised you, go re-read the documentation because it should be pretty clear on this.
I think I am confused between query parameters and params.
Let:
given this URL http://www.localhost:3000/NODE?a=Debasish&b=Biswas
We will have:
req.query
{
a: 'Debasish',
b: 'Biswas'
}
req.params
{
param1: 'NODE'
}
Here I am sending a query but want to receive params. That is where I go wrong.
For better understanding check :
Node.js: Difference between req.query[] and req.params
Related
I'm trying to create a basic login script for an app using Express JS, and have been working on a POST function to perform the same task for me. However, whenever I try to echo back the parameters I'm passing (testing the script via Postman), the values are always undefined.
Would appreciate some help! Thanks :)
Code:
const express = require('express'),
app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.get('/',(request,response)=>{
response.send('This is a test message');
});
app.post('/login', (request,response)=>{
let uname = request.body.username;
let pword = request.body.password;
response.send('Username: ' + uname + ' and Password: ' + pword);
});
//Binding the server to a port(3001)
app.listen(3001, () => console.log('express server started at port 3001'));
JSON being passed:
{
"username":"testuname",
"password":"passw0rd"
}
What you have works fine.
You are probably not specifying the Content-Type of your request to be application/json when testing.
I think you should try as like as give below:
It works on my machine. As you might have seen that, I have select raw and JSON(application/json) which you might have been missing.
im trying to create a simple webpage with some server side functions but somehow 2 things arent working as they supposed to work.
via html button im running a clientside javascript that does a http post request.
Client side javascript
httpRequest = new XMLHttpRequest()
httpRequest.open('POST', '/test2')
httpRequest.send(var1,var2,var3,var4);
Server.js
var express = require('express');
var bodyParser = require("body-parser");
var dbFunc = require("./dbFunctions.js");
var app = express();
var path = require('path');
var port = 8888;
//allow to use body-parser
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
//allow to use static files
app.use(express.static("public"));
//listen to smth
app.post('/test2', function (req, res) {
console.log("worked");
});
//start server
app.listen(port);
console.log("Server running on port" + port);
My server detects this post http request and does the "console.log" but how do i get the parameters from the http.request as a variable? I tried to work with bodyParser but somehow my object is always empty.
Another thing is, ive created another Javascript file(dbFunctions.js) and also implemented it in the server file but if i try to run a function(dbFunc.test("hello") for example) it says "dbFunc.test is not a function".
dbFunctions.js
function DBFunctions(){
function test(a){
console.log(a);
}
}
Ive also tried to do something like this, but this gave me the same error.
function test(a){
console.log(a);
}
Could someone give me a hint or tell me what i am missing?
Answer1:
The way you are sending data into post request is wrong, you slould send in format of,
xhttp.send("val1=val1&val2=val2");
httpRequest = new XMLHttpRequest()
httpRequest.open('POST', '/test2')
httpRequest.send(var1=var1&var2=var2&var3=var2&var3=var3);
To POST data like an HTML form, add an HTTP header with setRequestHeader(). Specify the data you want to send in the send() method:
httpRequest = new XMLHttpRequest()
httpRequest.open('POST', '/test2')
httpRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
httpRequest.send(var1=var1&var2=var2&var3=var2&var3=var3);
In your server.js, use req.body to get those values.
app.post('/test2', function (req, res) {
console.log("worked");
console.log(req.body)
});
XMLHttp request example
Answer2:
From your dbFunctions.js file you should export your function using module exports in node js.
dbFunctions.js:
var exports = module.exports = {};
exports.test = function(a) {
console.log(a);
};
You can also do as,
module.exports = {
test: function(a) {
console.log(a)
},
}
Now in your server.js
var dbFunc = require("./dbFunctions.js");
dbFunc.test();
Node js module exports
All your posted variables will be available in req.body try console.log(req.body).
Secondly you most probably not exporting test function from dbFunction.js, that's why getting "dbFunc.test is not a function" because dbFunc.test is undefined.
Note: As mentioned in one of the comment, you need to use httpRequest.send(var1,var2,var3,var4); in the right way. It does not expect multiple parameters.
Like: httpRequest.send("var=var1&var1=var2")
Please refer: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/send
Note: I am very new to express
var express = require('express');
var app = express();
app.get('/', function(req, res) {
res.send('id: ' + req.params.id + ' and name: ' + req.params.name);
});
var things = require('./things/things.js');
//both index.js and things.js should be in same directory
app.use('/things', things);
//Simple request time logger
app.use('/',function(req, res, next){
console.log("A new request received at " + Date.now());
//This function call is very important. It tells that more processing is
//required for the current request and is in the next middleware
//function/route handler.
next();
});
app.listen(3000);
I am learning about middleware functions and am trying to show a console.log message when I go to localhost:3000, but nothing shows up in my console, what am I missing here?
The problem is that Express passes requests to both middleware and route handlers in order of their declaration. If any of them are able to handle the request (by sending back a response), any other matching middleware or route handlers that got declared later won't get called.
That's what's happening in your situation, where your middleware is declared after the route handlers.
Try moving your middleware to the front:
app.use('/',function(req, res, next){
console.log("A new request received at " + Date.now());
next();
});
app.get('/', function(req, res) {
res.send('id: ' + req.params.id + ' and name: ' + req.params.name);
});
var things = require('./things/things.js');
app.use('/things', things);
First, you need to check the file structure. If index.js and things.js are in the same directory then you need to change the require function to var things = require('./things.js');
Next, verify that you are looking in the correct place, the console.log() message will appear in the terminal window where you loaded the express server, not in the console in your web browser.
The correct 'id' and 'name' of the parameters in get is like this
app.get('/:id/:name', function(req, res) {
res.send('id: ' + req.params.id + ' and name: ' + req.params.name);
});
The console module provides a simple debugging console that is similar
to the JavaScript console mechanism provided by web browsers. https://nodejs.org/api/console.html
Node Server generated console.log message in our terminal logs (Not on the browser).
https://expressjs.com/en/starter/hello-world.html
Related: https://www.twilio.com/blog/guide-node-js-logging
I have the following code:
var express = require('express');
var app = express();
app.use(express.bodyParser());
app.use(express.cookieParser());
var port = Number(process.env.PORT || 5000);
app.get('/test/:id', function(req, res) {
res.send(req.params);
});
app.listen(port);
console.log("Listening on port " + port);
When I hit http://localhost:5000/test/12345 in my browser, I see:
[]
But I'm expecting to see the populated req.params object with id: 12345. Any idea what I'm doing wrong?
Thanks.
Checked and saw that req.params is actually an associative array, which is almost similar to object but not quite. Not sure why express defined it as such. The only benefit it gets is the added length property for an array. And res.send will try to JSON.stringify your output, which in turn will see that it's an array and only take care of indexes which are numeric. Hence the empty [] as return value.
You can validate this by doing -
var myParams = {};
Object.keys(req.params).forEach(function(key){
myParams[key] = req.params[key];
});
res.send(myParams);
You can also see that JSON.stringify only cares about numeric index by defining your route as such -
app.get('/test/:0', function(req, res) {
res.send(req.params);
});
The response object will be named after your id. If you check it in your browser's traffic you can see a file called 12345. Though you can check that your server gets the id by logging it on the server side.
app.get('/test/:id', function(req, res) {
console.log(req.params);
res.send(req.params);
});
If you want to pass variables to a view you might want to use the res.render(...) function where you can pass in arguments.
To get the 123451 send the res.send(req.params.id);.
The reason why you are not getting anything using res.send(req.params) is because req.params is an instance of Array and default mechanism tries to covet an array into string which is giving you [].
What you could do to see all params is as follows:
app.get('/test/:id', function(req, res) {
res.send(require('util').inspect(req.params));
});
That will give you output like (using this URL http://localhost:5000/test/12345):
[ id: '12345' ]
That approach will also work with routes having more parameters e.g. the following code snippet and that request http://localhost:5000/test/name/234
app.get('/test/:name/:id', function(req, res) {
res.send(require('util').inspect(req.params));
});
will give you:
[ name: 'name', id: '234' ]
Alternatively, if you would like to get JSON formatted output of a JavaScript object, you can use res.json. But note that json will also generate [] if you perform res.json(req.params) as it will render req.params array in a standard way.
I hope that will help.
Note that as of 9th April 2014 (Express version 4.0.0) req.params is an object instead of an array so you should not have similar issues with v4.0.0 and your code should work as expected.
app.get('/test/:id', function(req, res) {
res.send(req.params);
});
The problem isn't your middleware. Neither bodyParser nor cookieParser provide the named url parameter parsing. That being said, your code looks correct to me. Are you absolutely certain you restarted your node server after making the code change?
I'm getting around to using domains and am trying a couple of Express domain middleware packages:
https://github.com/brianc/node-domain-middleware
https://github.com/baryshev/connect-domain
According to the usage docs on the first one I should have access to process.domain but it is undefined.
I am basically doing this in my app.js
var express = require('express'),
domains = require('express-domain-middleware');
var app = exports.app = express();
app.use(domains);
And in a controller:
exports.index = function(req, res, next) {
console.log(process.domain); //undefined
};
What gives?
You might want to check (using console.log or breakpoints) to make sure this line is happening before your index method is getting called:
express.use(domain);
I don't know how your app is structured but order of app.use is usually the case.
Your app.get('/someurl', yourcontroller.index) should come after app.use(domain).
Ok - it's due to a Mongo call in my middleware. Evidently all database calls have to be wrapped.
var d = domain.create();
d.run(function () {
client.query('...', d.intercept(function (rows) {
// ... use rows (note, first arguments error was "intercepted" by the domain)
}));
});
Reference: https://github.com/felixge/node-mysql/issues/308