Express Server - Cannot POST / [duplicate] - javascript

This question already has answers here:
How to access POST form fields in Express
(24 answers)
Closed 7 years ago.
I recently followed a simple tutorial on how to build an Express server (https://codeforgeek.com/2014/06/express-nodejs-tutorial/).
I am trying to extend the code from this tutorial so that I can respond to post requests. I want to do this by updating a json file (that happens to be filled with 'user comments', and then rerendering at '/'
./server.js:
var express = require('express');
var app = express();
// routing configuration
require('./router/main')(app);
// ejs configuration
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.engine('html', require('ejs').renderFile);
// run the server
var server = app.listen(8080, function(){
console.log('Express server listening on port 8080');
});
./router/main.js (routers):
var fs = require('fs');
var ejs = require('ejs')
module.exports = function(app){
app.get('/', function(req, res){
var comments = JSON.parse(fs.readFileSync(__dirname + '/../comments.json'));
res.render('index.ejs', comments);
});
app.post('/', function(req, res){
console.log('here in post');
var name = req.body.name;
var message = req.body.message;
var newComment = {"name": name, "message": message};
var comments = JSON.parse(fs.readFileSync(__dirname + '/../comments.json'));
comments.push(newComment);
fs.writeFileSync(__dirname + '/../comments.json', comments, 'utf8');
//redirect to a 'get' on '/'
res.redirect('/');
});
app.get('/about', function(req, res){
res.render('about.html')
});
}
./views/index.ejs:
<div>
<div>
<h1> Joe's Forum </h1>
<a href='/about'> (about) </a>
</div>
<div>
<ul>
<% comments.forEach( function(comment){ %>
<li>
<%= comment.name %> : <%= comment.message %>
</li>
<% }); %>
</ul>
</div>
<h2> Enter a new comment </h2>
<form action='/' method="post">
Enter your name: <input type='text' name='name'> <br><br>
Enter your message: <input type='textarea' name='message'> <br><br>
<input type='submit' value='Submit'>
<form>
</div>
./comments.json:
{
"comments": [
{"name":"Joe", "message" : "What advantages does Node.js afford the web developer?"},
{"name": "John", "message": "Asynchronous IO helps us to keep our pages responsive even if the server is fetching data"}
]
}
When I try to submit a new comment from my form, all I see is this:
"Cannot POST /"
Can someone please explain why I might be getting this error? Thanks

There are actually a couple of problems, but the main one is that you don't have a body parser - the module that converts a node stream in the POST to a req.body. I am currently only familiar with bodyParser, and you should probably research that a bit. Although it is shown in Express 4.x documentation, you get a deprecation message when you run the server.
The other problem is the issue of comments.push. That should be comments.comments.push. The following works:
router.js:
var fs = require('fs');
var ejs = require('ejs')
module.exports = function(app){
app.get('/', function(req, res){
var comments = JSON.parse(fs.readFileSync(__dirname + '/../comments.json'));
res.render('index.ejs', comments);
});
app.post('/', function(req, res){
console.log('here in post');
console.log(req.body)
var name = req.body.name;
var message = req.body.message;
var newComment = {"name": name, "message": message};
var comments = JSON.parse(fs.readFileSync(__dirname + '/../comments.json'));
comments.comments.push(newComment);
fs.writeFileSync(__dirname + '/../comments.json', JSON.stringify(comments), 'utf8');
//redirect to a 'get' on '/'
res.redirect('/');
});
app.get('/about', function(req, res){
res.render('about.html')
});
}
and server.js:
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.urlencoded())
// routing configuration
require('./router/main')(app);
// ejs configuration
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.engine('html', require('ejs').renderFile);
// run the server
var server = app.listen(8080, function(){
console.log('Express server listening on port 8080');
})

Related

Updating Json file in node but fiving previously saved results

I have a simple node script in which I update the db.json file through the form. It updates the file but when I render it in response for a get or post out it gives previous results only.
var cors = require('cors')
const express = require('express');
const app = express();
var jsonfile = require('jsonfile');
var file = './db.json'
var filex = require('./db.json')
app.engine('html', require('ejs').renderFile);
app.use(cors())
const http = require('http');
const port = process.env.PORT || 3000
const bp = require('body-parser')
app.use(bp.json())
app.use(bp.urlencoded({ extended: true }))
app.set('view engine', 'html')
// Defining get request at '/' route
app.get('/', function(req, res) {
res.send("<html><head><title>Json</title></head><body><form id='form1' action='/gettingdata' method='post'><input type='text' name='usrid' /><button type='submit' form='form1' value='Submit'>Submit</button></form></body></html>")
});
app.post('/gettingdata',function(req,res){
var user_id = req.body.usrid;
var obj = JSON.parse(user_id)
jsonfile.writeFileSync(file, obj,{flag: 'w'});
res.send('updated');
})
app.post('/api',function(req,res){
res.send(filex)
})
app.get('/api',function(req,res){
res.send(filex)
})
//extra
app.post('/api/v1/users/initial_authentication',function(req,res){
res.send(filex)
})
app.get('/api/v1/users/initial_authentication',function(req,res){
res.send(filex)
})
app.listen(port, function(req, res) {
console.log("Server is running at port 3000");
});
It only gives updated results on redeveloping of server.
var filex = require('./db.json')
So, filex only load the file when the server starts. If you try to get the most updated content of file db.json, please re-load the file.
I guess res.send(require('./db.json')) may work as expected.
I have solved this issue using
delete require.cache[require.resolve('./db.json')]

getting "Cannot GET /public/signup.html" error in express js

Very new to express and file system and don't have much idea about directories so getting this error.
var express= require('express');
var path= require('path');
var mysql= require('mysql');
var bodyParser= require('body-parser');
var app= express();
app.get('/', function(req, res) {
res.set( {
'Access-control-Allow-Origin': '*'
});
return res.redirect('/public/signup.html');
}).listen(2121);
console.log('server Running on : 2121');
app.use('/public',express.static(__dirname +"/public"));
Getting error "Cannot GET /public/signup.html"
My directories is:
-Express
--Server.js
--public
---signup.html
Looks like your code is a little jumbled up. Separate out your port listener - this should always come last. Add your routes and middleware before that as individual calls to app, and also register your get request to redirect back to your server to the signup html.
This should work:
var express = require("express");
var path = require("path");
var port = 2121;
var app = express();
// Register Middlewares/Headers
app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "*");
next();
});
// Register Static
app.use("/public", express.static(__dirname + "/public"));
// Register redirect
app.get('/', (req, res) => {
res.redirect(req.baseUrl + '/public/signup.html');
});
app.listen(port, () => {
console.log("server Running on : ", port);
});
You're calling listen on app before you call use on your middleware and there are a few mistakes in your code. I think this should work:
app
.use('/public',express.static(`${__dirname}/public`))
.get('/', (req, res) => {
res.header({
'Access-control-Allow-Origin': '*'
});
res.redirect(`${req.baseUrl}/public/signup.html`);
})
.listen(2121);
You should provide
app.use('/public',express.static(__dirname +"/public"));
Before you using app.get
Full example:
var express= require('express');
var path= require('path');
var mysql= require('mysql');
var bodyParser= require('body-parser');
var app= express();
app.use('/public',express.static(__dirname +"/public"));
app.get('/', function(req, res) {
res.set( {
'Access-control-Allow-Origin': '*'
});
return res.redirect('/public/signup.html');
}).listen(2121);
console.log('server Running on : 2121');

Why is 'Cannot Get/' being shown for a simple render of pug?

Trying to set up a basic Express server with a basic pug template.
Can you please tell me what I'm doing wrong here?
'use strict';
//Require Express
var express = require('express');
var app = express();
//Require Pug
var pug = require('pug');
//Require Twitter
var Twitter = require('twitter');
//Set view engine to serve middleware
app.set('view engine', 'pug');
//Set where to look for templates
app.set('views', __dirname + '/templates');
//Set up style sheets
app.use('/static', express.static(__dirname + '/public'));
//Access keys to access twitter account
var config = {
"consumerKey": "",
"consumerSecret": "",
"accessToken": "",
"accessTokenSecret": ""
};
//instantiate twitter client
var client = new Twitter(config);
//Log whether
var error = function (err, response, body) {
console.log('ERROR [%s]', err);
};
var success = function (data) {
console.log('Data [%s]', data);
};
//Set up server on Port 3000
app.listen(3000, function() {
console.log("The frontend server is running on port 3000!");
});
//Render when appropriate
//Tell app to render template
app.get('/'), function(req, res){
res.render('index', {title: 'Hey', message: 'Hello there!'});
}
I'm getting back The frontend server is running on port 3000! in the console.
What am I missing?
I'd really appreciate any help please
You're calling app.get() wrong. You're doing
app.get('/'), function(req, res){
...
Which is two statements separated by the comma operator. The correct syntax is to pass the function as the second argument:
app.get('/', function(req, res){
...
});

How to call a server side function from client side (e.g. html button onclick) in Node.js?

I need a complete basic example in Node.js of calling a server-side function from (client side) html button onclick event, just like in ASP.NET and C#.
I am new to Node.js and using the Express framework.
Any help?
IMPROVED QUESTION:
//server side :
var express = require('express');
var routes = require('./routes');
var user = require('./routes/user');
var http = require('http');
var path = require('path');
var app = express();
// all environments
app.set('views',__dirname + '/views');
app.set('port', process.env.PORT || 3000);
app.engine('html', require('ejs').renderFile);
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.static(path.join(__dirname, 'public')));
app.set('view engine', 'html');
app.use(app.router);
app.get("/",function(req,res)
{
res.render('home.html');
});
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
app.get('/', routes.index);
app.get('/users', user.list);
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
//Client Side
<input type="button" onclick="" /> <--just want to call the serverside function from here-->
Here's an example using Express and a HTML form.
var express = require('express');
var app = express();
var http = require('http');
var server = http.createServer(app);
app.use(express.bodyParser());
app.post('/', function(req, res) {
console.log(req.body);
res.send(200);
});
server.listen(process.env.PORT, process.env.IP);
The code above will start an instance of Express, which is a web application framework for Node. The bodyParser() module is used for parsing the request body, so you can read post data. It will then listen for POST requests on the route /.
<form method="post" action="/">
<input type="test" name="field1">
<input type="test" name="field2">
<input type="submit">
</form>
And if you submit that form, in req.body for the route /, you will get the result:
{ field1: 'form contents', field2: 'second field contents' }
To run a function, just put it inside the POST handler like this:
var foo = function() {
// do something
};
app.post('/', function(req, res) {
console.log(req.body);
res.send(200);
// sending a response does not pause the function
foo();
});
If you don't want to use Express then you can use the native HTTP module, but you'd have to parse the HTTP request body yourself.
var http = require('http');
http.createServer(function(request, response) {
if (request.method === 'POST') {
var data = '';
request.on('data', function(chunk) {
data += chunk;
});
request.on('end', function() {
// parse the data
foo();
});
}
}).listen(80);

Node.js express post parameters always undefined

I am pretty new to Node.js development, and I am aware that there are several stack overflow questions like this already, unfortunately none seem to fix my problem. So I feel all I can do is ask my question
So I am use Node.js with Express and the Jade view engine.
I based some of my code on this article : http://howtonode.org/express-mongodb
Anyway here is what I have
The node app :
var express = require('express');
var home = require('./routes/home');
var d3demo = require('./routes/d3demo');
var PersonProvider = require('./public/javascripts/personProvider').PersonProvider;
var personProvider = new PersonProvider('localhost', 27017);
var LinkProvider = require('./public/javascripts/linkProvider').LinkProvider;
var linkProvider = new LinkProvider('localhost', 27017);
var http = require('http');
var path = require('path');
var app = express();
//=============================================================================
// EXPRESS SETUP
//=============================================================================
app.configure(function(){
app.set('port', process.env.PORT || 2000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
//app.use(require('connect').bodyParser());
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(require('stylus').middleware(__dirname + '/public'));
app.use(express.static(path.join(__dirname, 'public')));
});
app.configure('development', function () {
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});
app.configure('production', function () {
app.use(express.errorHandler());
});
//=============================================================================
// ROUTING
//=============================================================================
app.get('/home', function (req, res) {
home.homeGet(req, res, commonHelper, personProvider, linkProvider);
});
app.post('/home', function (req, res) {
home.homePost(req, res, personProvider);
});
var server = http.createServer(app);
server.listen(app.get('port'), function(){
console.log("Express server listening on port " + app.get('port'));
});
and this is the Home route
/*
* GET home page.
*/
exports.homeGet = function(req, res, commonHelper, personProvider, linkProvider){
commonHelper.seedData(personProvider, linkProvider, function() {
res.render('home');
});
};
exports.homePost = function (req, res, personProvider) {
var newUserEmail = req.body.email;
console.log(req.body.length);
//console.log(x);
//var email = req.param('Email');
console.log("/Home posted Email :" + newUserEmail);
personProvider.save({
//email: req.param('Email'),
email: newUserEmail,
}, function (error, docs) {
if(error == null) {
res.redirect('/d3demo');
} else {
res.render('home');
}
});
};
And this is the jade view
extends layout
block head
link(rel='stylesheet', href='/stylesheets/home.css')
script(src='/javascripts/home.js')
block content
form(method='post', id='homeForm', action='http://localhost:2000/home')
div(id='dialog', title='error', style='display:none;')
p You need to supply a valid email
div(id='NewDetailsArea')
p Enter your email address, and then click enter
| <input type="text" id="email" class="email"></input>
div#homeSubmit
input(type='submit', value='Enter', id='enterEmail')
Which gets rendered to this
<form method="post" id="homeForm" action="http://localhost:2000/home">
<div id="dialog" title="error" style="display:none;">
<p>You need to supply a valid email</p></div>
<div id="NewDetailsArea">
<p>Enter your email address, and then click enter </p>
<input type="text" id="email" class="email">
</input><div id="homeSubmit"><input type="submit" value="Enter" id="enterEmail">
</div>
</div>
</form>
So the problem:
Well the problem is actually pretty simply. Within the function
homePost = function (req, res, personProvider)
I would like to be able to get the value of the 'email' form field
I have tried req.param('email'), req.body.email I have tried the standard express.bodyParser() and also the connect (which someone mentioned in another answer) one require('connect').bodyParser(), but alas all I get is undefined.
Also if I try and console.log(req.body) I get undefined
What am I doing wrong?
You need to supply a name attribute for the email input. The name is what gets sent when the form is submitted:
<input type="text" id="email" name="email" class="email">

Categories

Resources