nodejs throws cannot post error - node.js

I am trying to post the data from html form but it is showing an error "cannot POST".
This is my code:
controller/InquiryDetails.js:
var mongoose = require('mongoose'),
InquiryDetails = mongoose.model('InquiryDetails');
exports.add = function(req, res) {
InquiryDetails.create(req.body, function (error, details) {
if (error) return console.log(error);
return res.send(details);
});
}
routes/Inquiry.js
var express = require('express');
var router = express.Router();
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.urlencoded({extended:true}));
app.post('/InquiryDetails', function(req,res,err){
if(err) console.log(err);
res.json(req.body);
console.log(req.body);
});
module.exports = router;
model/InquiryDetails.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var myskyll = new Schema({
name: String,
email: String,
state: String,
country: String,
school: String,
profession: String,
phone: Number
});
mongoose.model('InquiryDetails', myskyll);
app.js:
var express = require('express');
var mongoose = require('mongoose');
var request = require('request');
var connect = require('connect');
var serveStatic = require('serve-static');
connect().use(serveStatic(__dirname+"/index.html")).listen(8080);
var mongoUri = 'mongodb://localhost/myskyll';
mongoose.connect(mongoUri);
var db = mongoose.connection;
db.on('error', function () {
throw new Error('unable to connect to database at ' + mongoUri);
});
var app = express();
console.log("connection successfull");
app.configure(function(req,res){
app.use(express.bodyParser());
});
app.use(express.static(__dirname + "/" ));
require('./models/InquiryDetails');
require('./routes/Inquiry');
app.listen(3000);
console.log('Listening on port 3000...');
index.html:
<form method="post" id="form1" action="InquiryDetails">
Your Name:<span class="imp">*</span><br/><input type="text"
name="name" placeholder="Firstname Lastname" class="textbox"
autofocus required pattern="[A-Za-z-0-9]+\s[A-Za-z-'0-9]+"
title="'Firstname' <space> 'Lastname'"/> <br/><br/>
Email:<span class="imp">*</span><br/><input
type="email" name="email" placeholder="Email" class="textbox"
required/><br/><br/>
city:<span class="imp">*</span><br/><input type="text" name="city"
placeholder="city" class="textbox" required/><br/><br/>
State/Country:<span class="imp">*</span><br/>
<input type="text" name="country"
placeholder="State/Country" class="textbox" required /><br/>
<br/>
School/Institution:<span class="imp">*</span><br/><input
type="text" name="school" placeholder="Your School or
Institution" c lass="textbox" required /><br/><br/>
Your Profession:<br/><input type="text" name="profession"
placeholder="Profession" class="textbox"><br/><br/>
Phone:<br/><input type="text" name="phone" placeholder="Phn. no.
with country code" class="textbox" pattern="\+[0-9]+" title="Only
digits" /><br/><br/>
<input type="submit" value="Submit"
class="btn3"/>
<input type="reset" value="Clear" class="btn3" />
</form>
I have tried in postman API client to post the data but it shows 404 status while posting the data.
Do I have any problem in my code?
Any suggestion will be appreciated!

You are creating multiple app objects. One in app.js and a different one in routes/Inquiry.js.
For this type of application, you will want to be using only one app object that you share with anyone who needs it because only one of them is actually registered with your web server and is being used.
That is likely why your app.post() handler is not working because it's registered on the wrong app object - the one that is not connected to a live server.
There are several other things that look incorrect in the code:
The third argument to an app.post() callback is a next() function reference, not the err that you have declared and are testing.
You are doing require('./models/InquiryDetails'); and that module exports some things, but you are not assigning the result of the require to anything so those exports are unusable.
You are initializing the connect module, but if you are using a recent version of Express that module is no longer needed as the functionality it used to provide for Express is now built into Express.

Related

Uploading a file with express-fileupload doesn't work

I'm attempting to upload a file with express-fileupload (express-fileupload) in Node js.
But I wasn't successfully yet.
My app.js (where my express server is running) looks like this:
const express = require('express');
const exphbs = require('express-handlebars');
const fileUpload = require('express-fileupload');
const app = express();
const port = 5000;
app.use(fileUpload({
debug: true
}));
app.use(express.static('./upload'));
const routes = require('./server/routes/task');
app.use('/', routes);
app.listen(port, () => console.log(`Listening on port ${port}`));
My task.js (where my routes are) looks like this:
const express = require('express');
const router = express.Router();
const taskController = require('../controllers/taskController');
router.post('/admin/fileUpload', taskController.fileUpload);
module.exports = router;
My taskController.js (where my routes are getting controlled) looks like this:
exports.fileUpload = (req, res) => {
let sampleFile;
let uploadPath;
if (!req.files || Object.keys(req.files).length === 0) {
res.render('admin', { error: `No files were uploaded!` });
} else {
sampleFile = req.files.sampleFile;
uploadPath = __dirname + '/upload/' + sampleFile.name;
sampleFile.mv(uploadPath, function (err) {
if (err) throw err;
res.render('admin', { alert: `File ${sampleFile.name} successfully uploaded!` });
}
}
}
My admin.hbs (I'm also using express-handlebars) looks like this:
<form method="POST" action="/admin/fileUpload">
<h2>Upload File</h2>
<input type="file" enctype="multipart/form-data" name="sampleFile">
<button type="submit">
</form>
So, my log looks like this when I start the express server:
[nodemon] starting `node app.js`
Listening on port 5000
Express-file-upload: Request is not eligible for file upload!
I'm trying to find the issue for hours but haven't had any luck yet.
So, it took me a while but I found my issue.
I've made a two little mistakes in my form and in my upload path.
<form method="POST" action="/admin/fileUpload">
<h2>Upload File</h2>
<input type="file" enctype="multipart/form-data" name="sampleFile">
<button type="submit">
</form>
Thats wrong. I've added the "enctype" in the wrong place. It should be in the form and not in the input field.
Solution for my form:
<form method="POST" action="/admin/fileUpload" enctype="multipart/form-data">
<h2>Upload File</h2>
<input type="file" name="sampleFile">
<button type="submit">
</form>
Solution for my upload path:
Instead of
uploadPath = __dirname + '/upload/' + sampleFile.name;
I need to do this
uploadPath = './upload/' + sampleFile.name;

Show User the error message when problem when logging in

I have just started working on an already existing Web application project. Right now when the user tries logging in with incorrect credentials , the page is getting redirected to 'relogin' page. Where the Message "Please enter valid credentials" is hardcoded in the HTML to show a "error message". I have been asked to add another functionality to the Application. I want to show the user the message which server returns.
For Example :-
If server response is
{ result : "false" , message : " Invalid email " }
i want to show "Please enter Valid email" to the user.
If server response is
{ result : "false" ,message : " Invalid password " }
i want to show "Please enter Correct Password" to the user.
,but because of the present code i am not able to do that.
Please help me with this task.
Thanks in advance.
I am attaching my app.js , passport.js , authenticate.js code. please inform if you need any more details.
--app.js--
var express = require('express');
var path = require('path');
var logger = require('morgan');
var bodyParser = require('body-parser');
var session = require('express-session');
var passport = require('passport');
var initPassport = require('./passport');
initPassport(passport);
var routes = require('./routes/routes');
var authenticate = require('./routes/authenticate')(passport);
app.use('/',routes);
app.use('/auth',authenticate);
'''
--authenticate.js--
var express = require('express');
var router = express.Router();
var path = require('path');
module.exports = function(passport) {
router.get('/logout', function(req, res){
req.logout();
res.redirect('/');
});
router.post('/login',passport.authenticate('login',{
successRedirect: '/',
failureRedirect: '/relogin',
}));
return router;
};
'''
--passport.js--
var LocalStrategy = require('passport-local').Strategy;
var pg = require('pg');
var path = require('path');
var fs = require('fs');
var Client = require('node-rest-client').Client;
var client = new Client();
module.exports = function(passport){
passport.use('login', new LocalStrategy({
passReqToCallback : true
},
function(req, username, password, done) {
var client = new Client();
client.get(serverHost+serverRoot+"/validateuser?username="+username+"& password="+password, function (data, response) {
// parsed response body as js object
// raw response
console.log("response from server ", data);
if(data.result == "true")
return done(null, username);
else
return done(null ,false );
});
}));
}
'''
EDIT 1 :-
There is no angular code for logging in.
All the procedure happens in html only.
I am attaching the HTML code. Thanks
HTML code :-
<body>
<div class="col-md-6 offset-3">
<form action="/auth/login" method="post" >
<div class="form-group mb-4 mt-4"><input id="email" class="form-control
form-control-rounded" type="text" name = "username"
placeholder="Username" ></div>
<div class="form-group mb-4 mt-4"><input id="password" class="form-control
form-control-rounded" type="password" name="password"
placeholder="Password"></div>
<button type = "submit" value = "Login" class="btn btn-rounded btn-primary btn-block mt-2">Sign In</button>
</form>
</div>
</body>
You can use res.render function to send data to your view. Documentation for the same is available at:
https://expressjs.com/en/api.html#res.render
Regarding the specific issue related to validation via passport.js have a look at:
Send data back with the Passport js failureRedirect method

Why is require('/routes')(app); not equivalent to having the same code in one app.js file?

The following lines of code deliver the localhost/join page.
routes.js file
module.exports = function (app){
app.get("/join", function (req, res){
res.render("join");
});
};
app.js file
var express = require("express");
var app = express();
require('./routes')(app);
app.listen(3000, function(){
console.log("Server started at localhost:3000. Ctrl+C to exit.");
});
join.ejs file
<h1> You can sign up here </h1>
<input type="email" placeholder="email address"> </input>
<br>
<input type="password" placeholder="password"> </input>
<br>
<input type="submit"> </input>
Yet when I try to create an app.post() route (which works when in the app.js file) it gives me the error
app not defined
Why would this be given for app.post() and not app.get()? Why is require('/routes')(app); not equivalent to having the same code in one app.js file?
Your app.js should look like follows:
var express = require('express')
var app = express()
require('./routes')(app);
app.listen(PORT-NUMBER)
If yes then it will helpful to know how your routes.js looks like with app.post() route.

Formidable always returns empty fields and files when I upload a file in Node.js

Basically I want to upload a csv file from local computer and parse it in the backend to do required operations. I'm attaching the csv file in the front end. Checked that its not empty. But I'm unable to fetch the same in the server.
Is there something I'm missing or doing in the wrong way?
Here is what I have tried till now.
Front end code:
<form id="myForm" method="POST" enctype="multipart/form-data" action='/testcsv' >
<input type="file" id="file" />
<input type="submit" value="Submit">
</form>
Backend Code:
var express = require('express');
var methodOverride = require('method-override');
var http = require('follow-redirects').http;
var formidable = require('formidable');
var app = express();
const fs = require('fs');
app.use(methodOverride('_method'));
var bodyParser = require('body-parser');
app.use(bodyParser.json()); // support json encoded bodies
app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies
app.post('/testcsv', requireLogin, function(req, res) {
var form = new formidable.IncomingForm();
form.parse(req, function(err, fields, files) {
console.log(err);
console.log(fields);
console.log(files);
});
});
Log Output:
null
{}
{}
This problem is caused by Frontend code, it has nothing to do with Backend code (formidable).
For the following console.log statement:
console.log(err);
console.log(fields);
console.log(files);
err is null because there is no error.
fields is {} because in the form, all input fields are file selector. fields in formidable only indicate plain input field, such as <input type="text">.
files is {} because the name of file selector in the form is missing.
To get expected value, here is an example form:
<form id="myForm" method="POST" enctype="multipart/form-data" action='/testcsv' >
<input type="text" name="testtext" />
<input type="file" id="file" name="testfile" />
<input type="submit" value="Submit">
</form>
The console.log result for above form would be:
null
{ testtext: '....' }
{ testfile: File....}

Post request saving only versionKey with Mongoose and Express

I am trying to save a number and a few string values to a MongoDB and even though the code makes perfect sense to me, returns no errors and creates an entry in the database, all I get is just a versionKey, something like this:
{
"_id": {
"$oid": "58052711f319bc041c5ebdac"
},
"__v": 0
}
I thought I'd try just saving the number and the title first to see if they get saved, but they don't, as you can see above.
Every RESTful API and Express "post" request tutorial and answer I find seems to do it differently!
Also, is it supposed to show the res.json in plaintext for me to format or render somehow, or is it supposed to show the value of the property message:?
Here is the code
// modules =======================================================
const express = require('express')
const app = express()
const mongoose = require('mongoose')
// configuration =================================================
const db = require('./config/db')
// mongoose ======================================================
mongoose.connect(db.url)
const PostSchema = new mongoose.Schema({
number:Number,
title:String,
body:String,
images:String
}, { collection: 'posts' })
const posts = mongoose.model('Post', PostSchema)
// routes ========================================================
app.post('/api/post', function(req, res) {
var post = new posts()
post.number = req.body.number
post.title = req.body.title
post.save(function(err) {
if (err) res.send(err)
res.json({ message: 'Post saved'})
})
})
Here is my HTML5 form
<form action="/api/post" enctype="multipart/form-data" method="post">
<label for="number">Post Number:</label>
<input type="number" name="number" size="2" placeholder="required" required /><br />
<label for="title">Title:</label>
<input type="text" name="title" placeholder="optional" /><br />
<label for="body">Text:</label><br />
<textarea name="body" cols="80" rows="20" placeholder="optional"></textarea><br />
<label for="images">Images:</label>
<input type="text" name="images" placeholder="optional" />
<span class="form-hint">Comma separated file names, e.g. image1.jpg,image2.jpg,image3.png</span><br />
<input type="submit" value="Submit" />
</form>
My middleware that comes just before the routes in server.js
// middleware ====================================================
app.use(bodyParser.json()) // parse application/json
app.use(bodyParser.json({ type: 'application/vnd.api+json' })) // parse application/vnd.api+json as json
app.use(bodyParser.urlencoded({ extended: true })) // parse application/x-www-form-urlencoded
app.use(methodOverride('X-HTTP-Method-Override')) // override with the X-HTTP-Method-Override header in the request
app.use(express.static(__dirname + '/public')) // set static files location
First question, the encoding must match what you have Express parsing (in this case it wasn't multipart/form-data but application/json, 'application/vnd.api+json', and application/x-www-form-urlencoded. Removing the encoding type you were specifying fixes that.
Second, the response will be a simple JSON object:
{
"message": "Post saved"
}

Resources