How are the req and res objects created in Node.js? - node.js

I understand what the req and res objects contain, what they are used for, and when they are created, but I was wondering how they are created.

The req and res objects that you are referring to come from an npm package called express. Express is a lightweight package that allows you to handle HTTP requests on your node server.
Below is a small example of how to use the package with some example HTTP endpoints.
In the example, I also use a package called 'body-parser' this package is used to parse any HTTP requests with a JSON body. The package puts the parsed body into the req object at the key body, as can be seen in the code example.
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.get('/', (req, res) => {
// Handle GET / request here
});
app.post('/', (req, res) => {
// Handle POST / request here
// Get body of request
var body = req.body;
});
app.listen(8080, () => console.log('Listening on port 8080'));

req and res are the component of Express framework of Node package manager(npm) and is used to respond as per the request created by the user.
//To print Date as string
const express = require("express");
const bodyparser = require("body-Parser");
const app = express();
app.get("/", function(req, res) {
var today = new Date();
var options = {
weekday: "long",
year: "numeric",
month: "long",
day: "numeric",
};
var day = today.toLocaleDateString("en-US", options);
res.render("list", {
kindOfDay: day
});
});
app.post("/", function(req, res) {
var item = req.body.selectSection;
items.push(item);
res.redirect("/");
});
app.listen("3000", function() {
console.log(" the server is runnimg in port 3000");
});

Related

How to send response from a post request in node.js?

I am trying to send response from post requests and on internet I have seen I have to use res.end but it does not seem to work in my case. I have done post requests in the past succesfully but now I need to do them without loading the website, so it has to be asynchronous for each post request.
This is what I have:
Game.js:
textModalContent1.addEventListener("click", () => {
//Ask for username
let username = prompt("Enter your new username");
$.post("/addUser",{username: username}, function(data){ //I use jQuery for post requests
console.log(data);
});
});
index.js:
const express = require('express');
const app = express();
app.use('/assets', express.static('./assets/'));
var bodyParser = require('body-parser')
app.use( bodyParser.json() );
app.use(bodyParser.urlencoded({
extended: true
}));
app.get('/', function (req, res) {
res.render('./index.ejs', {});
});
app.post('/addUser', function(req, res) {
//console.log(req.body.username)
res.end("hello"); //this should send "hello" to the client
});
app.listen(process.env.PORT || 14532);
Each time I enter a username, should appear "hello" on my web browser console but it does not.
What am I doing wrong?

Problems POSTing json to Node/Express server from Axios/React

I'm current working on a web application using Node.js with Express in the back-end and React.js in the front end. In attempting to post user data to the Node server, through axios, I am running into an issue. When I make a post with the x-www-form-urlencoded content type, the front end will post to the server but the entire JSON of the posted data appears in the key field of the first element. When I change the content type to json it stops posting anything from the front end. I have tried cUrling to the server, and curling a JSON post will get accepted by the server.
React code to post to server
handleSubmit()
{
var form=this;
var axiosConfig = {
headers: {
'content-type': 'application/json; charset=utf-8'
}
}
axios.post('http://localhost:8080/api/login/', {
'username': form.state.username,
'password': form.state.password
}, {headers: {'content-type': 'application/json'}});
};
Server code for api endpoint
//From server.js
const express=require('express');
const session=require('express-session');
const bodyParser=require("body-parser");
const path = require('path');
var login = require('./routers/login')
var port = process.env.PORT || 8080;
var app=express();
app.use(session({'secret': 'thealphabetbackwardsiszyxwvutsrqponmlkjihgfedcba'}));
app.use(bodyParser.urlencoded({ extended: true}));
app.use(bodyParser.json());
//...
app.use('/api/login', login);
//from login.js
/* Router for login system
When user attempts to log in, check their credentials
If the user successfully logs in, create a session
If user enters invalid credentials prompt them
*/
const path = require('path');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const user = require("./../models/UserSchema")
mongoose.connect('mongodb://localhost/newt');
const express = require('express');
const router = express.Router();
router.get('/', function (req, res)
{
console.log("Test");
})
router.post('/', function(req, res)
{
console.log(req.body);
res.end();
})
// To create test user use path localhost:8080/api/login/testing
router.get('/test', function (req, res)
{
var db = mongoose.connection;
var test = new user({
username: "joesephschomseph",
email: "testUser#test.com",
fname: "Joe",
lname: "Schmoe"
})
test.save();
console.log("Created test user!");
});
module.exports = router
npm install --save const body-parser
in app.js include const bodyparser = require('body-parser');
app.use(bodyparser.urlencoded({ extended: false }));
app.use(bodyparser.json());
remove the single quotes from your 'username' and 'password'
console.log(req.body);

Can not post to server using node express

I am trying to post data from postman to my node server, I keep getting 404.
Is my code setup correctly to receive post to http://localhost:8080/back-end/test and if not how can I fix it ?
var express = require('express');
var request = require('request');
var nodePardot = require('node-pardot');
var bodyParser = require('body-parser');
var rp = require('request-promise');
var app = express();
var port = process.env.PORT || 8080;
// Start the server
app.listen(port);
app.use(bodyParser.json()); // support json encoded bodies
app.use(bodyParser.urlencoded({extended: true})); // support encoded bodies
console.log('Test server started! At http://localhost:' + port); // Confirms server start
var firstFunction = function () {
return new Promise (function (resolve) {
setTimeout(function () {
app.post('back-end/test.js', function (req, res) {
console.log(req.body);
var login = req.body.LoginEmail;
res.send(login);
resolve({
data_login_email: login
});
});
}, 2000);
});
};
I am posting LoginEmail and keep getting 404.
Move app.post() outside of the timeout, promise, and firstFunction.
There is no proceeding paths defined in your code, so the path must start with a /: /back-end/test.js. Don't forget the extension since you've defined it.

Query parameters in Express

I am trying to get access to query parameters using Express in Node.js. For some reason, req.params keeps coming up as an empty object. Here is my code in server.js:
const express = require('express');
const exphbs = require('express-handlebars');
const bodyParser = require('body-parser');
const https = require('https');
//custom packages ..
//const config = require('./config');
const routes = require('./routes/routes');
const port = process.env.port || 3000;
var app = express();
//templating engine Handlebars
app.engine('handlebars', exphbs({defaultLayout: 'main'}));
app.set('view engine', 'handlebars');
//connect public route
app.use(express.static(__dirname + '/public/'));
app.use(bodyParser.json());
//connect routes
app.use('/', routes);
app.listen(port, () => {
console.log( 'Server is up and running on ' + port );
});
And here is my routes file:
//updated
const routes = require('express').Router();
routes.get('/', (req, res) => {
res.render('home');
});
routes.post('/scan', (req, res) => {
res.status(200);
res.send("hello");
});
routes.get('/scanned', (req, res) => {
const orderID = req.params;
console.log( req );
res.render('home', {
orderID
});
});
module.exports = routes;
When the server is up and running, I am navigating to http://localhost:3000/scanned?orderid=234. The console log that I currently have in the routes.js file is showing an empty body (not recognizing orderid parameter in the URL).
orderid in the request is query parameter. It needs to be accessed via req.query object not with req.params. Use below code to access orderid passed in the request:
const orderID = req.query.orderid
Now you should be able to get 234 value passed in the request url.
Or try replacing the code for route /scanned with below:
routes.get('/scanned', (req, res) => {
const orderID = req.query.orderid
console.log( orderID ); // Outputs 234 for the sample request shared in question.
res.render('home', {
orderID
});
});
The reason that req.body keeps coming up as an empty object is that in get requests, such as those made by the browser on navigation, there is no body object. In a get request, the query string contains the orderid that you are trying to access. The query string is appended to the url. Your code can be rewritten as below:
routes.get('/scanned', (req, res) => {
const orderID = req.query.orderid
console.log( req );
res.render('home', {
orderID
});
});
A note, though, is that if you have AJAX posts firing within your client side code, your req.body will not be empty, and you can parse it as you would normally.

Request body undefined in supertest

I am testing an express API with supertest. I am trying to pass in body parameters into the test, as can be seen in the code snippets below, but it appears that the body parameters don't get passed in correctly since I get an error message that the body parameters are undefined.
Running the test with command mocha --recursive returns the following error:
Cannot read property 'email' of undefined
Below is the code from file email-suite.js referencing supertest
'use strict';
var express = require("express");
var bodyParser = require('body-parser');
var mongoose = require("mongoose");
var app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
var supertest = require("supertest");
var chai = require("chai");
var should = chai.should();
var api = require("../server.js");
describe("Email Module", function() {
this.timeout(25000);
before(function(done){
mongoose.createConnection(/* connectionstring */);
mongoose.connection.on('open', function(err) {
if(err) console.log(err);
console.log('connected to server');
});
done();
});
it("Check Email Count", function(done) {
var body = { email: "email#email.com" };
supertest(api)
.post("/emailCount")
.set('Accept', 'application/json')
.send(body) // body is undefined
.expect(200)
.expect('Content-Type', /json/)
.end(function(err, res) {
if(err) return done(err);
res.body.count.should.equal(2);
done();
});
});
});
Below is the code from file email-api.js
'use strict';
var express = require("express");
var bodyParser = require('body-parser');
var router = express.Router();
var app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
router.post('/emailCount', function(req, res) {
var email = req.body.email; // req.body is undefined
}
module.exports = router;
Below is the code from the file server.js
var express = require("express");
var app = express();
app.set("port", process.env.PORT || 3000);
var router = require("./user/email-api");
app.use('/', router);
app.listen(app.get("port"), function() {
console.log("App started on port " + app.get("port"));
});
module.exports = app;
Put body-parser always after express object and before every routes in main server file like this
var app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
//Router task start from here
Other wise always will get undefined since router call first and body parsed later.
Thank you abdulbarik for your answer. I want to add some extra information to aid clarity in case people are still getting undefined values for the request body object, and if (as in my case) your routers and tests are setup differently.
Here is the router that we shall test:
// router.js
const express = require("express");
const router = express.Router();
router.post("/", (req, res) => {
res.json({ success: true, data: req.body });
});
module.exports = router;
The following test code will result in the request body being undefined, and thus the test failing:
// router.test.js
const express = require("express");
const request = require("supertest");
const bodyParser = require("body-parser");
// set up the test app - this will fail
const app = express();
app.use("/routerPath", require("./router")); // this will cause the test to fail, as the router should be setup after the body-paser
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
// run the test
it("successful response", async () => {
const response = await request(app)
.post("/routerPath")
.send({
firstname: "John",
lastname: "Smith",
})
.set("Accept", "application/json");
expect(response.status).toEqual(200);
expect(response.body).toEqual({
success: true,
data: {
firstname: "John",
lastname: "Smith",
},
});
});
The reason why, as explained by abdulbarik, is that the body-parser code should always be before the router code, so that the parser runs before the router. To make the test pass, simply swap these lines around:
// set up the test app - this will work now
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use("/routerPath", require("./router")); // the router setup should happen after the body-parse setup
I hope that is a helpful clarification.

Resources