I'm using Mongoose to create a schema and attempting to add data to mongoDB via Postman and it is adding empty data to the db. I'm assuming my issue is the way the data is parsed from browser to server here is my app.js setup.
what is added to DB
{ "_id" : ObjectId("57846282c7b5f51d4c1742a9"), "__v" : 0 }
Here is the app.js file
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var multer = require('multer');
var routes = require('./routes/index');
var mongoose = require('mongoose');
var db = mongoose.connection;
mongoose.connect('mongodb://localhost/growlingRabbit');
var Page = require('./models/growling_rabbit_page_text.js');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
var storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, './uploads');
},
filename: function (req, file, callback) {
callback(null, file.fieldname + '-' + Date.now());
}
});
var upload = multer({ storage : storage}).single('userPhoto');
app.post('/api/photo',function(req,res){
upload(req,res,function(err) {
if(err) {
return res.end("Error uploading file.");
}
res.end("File is uploaded");
});
});
app.post('/api/text',function(req,res){
var text = new Page();
text.name = req.body.name;
text.save(function(err) {
if (err)
res.send(err);
res.json({ message: 'Text Added!' });
});
});
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
module.exports = app;
Here is the model
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var pageSchema = new Schema({
homePage: String,
communityPage: String,
eventPage: String,
contactPage: String,
galleryPage: String });
module.exports = mongoose.model('Page', pageSchema);;
Help, I'm sure it is something painfully obvious, unfortunately I cannot find it.
Well you create a Page with
var text = new Page();
text.name = req.body.name;
but your schema has no name property.
Change your schema like so:
var pageSchema = new Schema({
name: String,
homePage: String,
communityPage: String,
eventPage: String,
contactPage: String,
galleryPage: String });
Another problem could be using the wrong option for posting the data via Postman.
Ensure that x-www-form-urlencoded is used when testing your node API
Related
the error occured when i try post method to retrieve the data on the body (on postman) and store that data in to a mongodb local database then error occured says bad request with status 400
*this is app.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var mongoose = require("mongoose");
//mongoose make sure that only the fields that are specified in your Schema will be saved in the database
//strict query
mongoose.set('strictQuery',true);
mongoose.connect('mongodb://127.0.0.1:27017/EMP',{
useNewUrlParser: true,
useUnifiedTopology: true
},(err) => {
if(err)
console.log(err);
else
console.log('successfully connected to MongoDB');
});
var studentModel = require("./model/students.model");
var index = require('./routes/index');
var users = require('./routes/users');
var studentsRouter = require('./routes/students');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', index);
app.use('/users', users);
app.use('/students', studentsRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
*this is model.students.js file(path ./model/model.students.js)
var mongoose = require("mongoose");
//lets create schema
var studentSchema = mongoose.Schema({
studentId : Number,
firstName : String,
lastName : String,
age : Number,
dept : String
});
//lets create a model which is instance of schema
var studentModel = mongoose.model("students",studentSchema);
module.exports = studentModel;
*this is students.js file(path ./routes/students.js)
var express = require('express');
const studentModel = require('../model/students.model');
var router = express.Router();
/* GET users listing. */
router.get('/', function (req, res, next) {
res.send('students route works pretty well');
});
// route to add some data in the database
router.post('/add', function (req, res) {
// we are creating instance of model-studentModel called studentObj
let studentObj = new studentModel({
studentId: req.body.studentId,
firstName: req.body.firstName,
lastName: req.body.lastName,
age: req.body.age,
dept: req.body.dept
});
studentObj.save(function(err,studentObj){
if(err)
res.send(err);
else
res.send({message: "students data has been succefully added",object: studentObj});
});
var data = req.data;
console.log(data);
});
module.exports = router;
*this is error occured
it says status code 400 bad request with bad syntax i don't know why this happened i read documentations but i can't find what i am missing and causing this problem
<!DOCTYPE html>
<html>
<head>
<title></title>
<link rel="stylesheet" href="/stylesheets/style.css">
</head>
<body>
<h1>Unexpected token s in JSON at position 7</h1>
<h2>400</h2>
<pre>SyntaxError: Unexpected token s in JSON at position 7
at JSON.parse (<anonymous>)
at parse (C:\Users\Nile-Tech\3D Objects\project\Express JS\EMP\node_modules\body-parser\lib\types\json.js:89:19)
at C:\Users\Nile-Tech\3D Objects\project\Express JS\EMP\node_modules\body-parser\lib\read.js:128:18
at AsyncResource.runInAsyncScope (node:async_hooks:203:9)
at invokeCallback (C:\Users\Nile-Tech\3D Objects\project\Express JS\EMP\node_modules\raw-body\index.js:231:16)
at done (C:\Users\Nile-Tech\3D Objects\project\Express JS\EMP\node_modules\raw-body\index.js:220:7)
at IncomingMessage.onEnd (C:\Users\Nile-Tech\3D Objects\project\Express JS\EMP\node_modules\raw-body\index.js:280:7)
at IncomingMessage.emit (node:events:513:28)
at endReadableNT (node:internal/streams/readable:1359:12)
at process.processTicksAndRejections (node:internal/process/task_queues:82:21)</pre>
</body>
</html>
enter image description here
You sent malformed body with invalid JSON. You probably send <anonymous> which isn't a JSON valid format.
Check you request body and ensure that it contains a valid JSON and encoded properly.
I've got a basic Node JS app (as I'm just learning). I'm using express, express-generator, express-myconnection, and mysql.
The issue has to do with querying the database connection itself.
The app is designed using an MVC structure.
Edit: to start off, here is my "app.js":
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var index = require('./routes/index');
//var users = require('./routes/users');
var app = express();
var connection = require('express-myconnection');
var mysql = require('mysql');
app.use(
connection(mysql,{
"host":"localhost",
"user":"root",
"password":"root",
"port":3306,
"database":"fruits"
},'request')
);
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', index);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
I have a model file, "fruits.js":
var fruits = function(data, req){
this.data = data;
this.req = req;
}
fruits.prototype.data = {};
fruits.prototype.getAll = function(callback){
this.req.getConnection(function(err, connection){
console.log(connection);
//var q = connection.query("SELECT * FROM `fruits`", function(err, rows){
//callback(rows);
//});
});
};
module.exports = fruits;
Then I also have a controller file (index.js):
var express = require('express');
var router = express.Router();
var fruits = require('../models/fruits.js');
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
/*GET fruits page */
router.get('/fruits',function(req, res, next){
var f = new fruits({}, req);
f.getAll(function(fruitsObj){
console.log(fruitsObj);
res.render('fruits',{
"title":"Fruits!",
"fruits":fruitsObj
});
});
});
module.exports = router;
What happens is whenever the fruits route is navigated to, I can't query the database. It says that the "connection" from "this.req.getConnection" is "undefined".
Is there any reason why I can't retrieve the database connection and query it based on the contents of these two files? I'm positive I have all my packages installed. I even ran npm install for all them again to make sure.
Thanks for your help in advance.
I have uploaded the image in to a local directory using Busboy and passed
the path of the image to the MongoDB using Mongoose but now I unable to
retrieve the path
to display the image in my ejs view. I'm new to this nodejs. Please help me
to display the image.
Thank you Very much in Advance :)
var express = require('express'); //Express Web Server
var busboy = require('connect-busboy'); //middleware for form/file upload
var path = require('path'); //used for file path
var fs = require('fs-extra'); //File System - for file manipulation
var mongoose = require('mongoose');
var mongoClient = require('mongodb').mongoClient;
var objectId = require('mongodb').ObjectId;
var app = express();
app.use(busboy());
app.use(express.static(path.join(__dirname, 'public')));
mongoose.Promise = global.Promise;
mongoose.connect('mongodb://localhost:27017/postname');
/* ==========================================================
Create a Route (/upload) to handle the Form submission
(handle POST requests to /upload)
Express v4 Route definition
============================================================ */
app.set('view engine','ejs');
app.use(express.static(__dirname + '/public'));
var nameSchema = mongoose.Schema({
newfile: Object,
path: String
});
var compileSchema = mongoose.model('foods', nameSchema);
app.get('/', function(req, res, next) {
res.render('index',{'title': 'New post app'});
});
app.route('/')
.post(function (req, res, next) {
var fstream;
req.pipe(req.busboy);
req.busboy.on('file', function (fieldname, file, filename) {
console.log("Uploading: " + filename);
//Path where image will be uploaded
fstream = fs.createWriteStream(__dirname + '/public/uploads/' + filename);
var dirname = path.join(__dirname + '/public/uploads/' + filename);
file.pipe(fstream);
//mongo save
var paths = new compileSchema({newfile : dirname, passReqToCallback: true});
paths.save(function(err){
if(err) throw err;
compileSchema.find({newfile: dirname}, (err, result) =>{
console.log();
return result;
});
});
fstream.on('close', function () {
console.log("Upload Finished of " + filename);
//where to go next
res.redirect('/profile');
});
});
});
app.get('/profile', (req, res)=>{
res.render('profile',{photo: req.result});
});
var server = app.listen(3030, function() {
console.log('Listening on port %d', server.address().port);
});
My Ejs file is :
<img src='<%= photo.newfile %>' >
This is the typical process of writing and reading from Mongodb using Mongoose. I have not checked whether your streaming and other things work fine but the db workflow would be better this way.
var express = require('express'); //Express Web Server
var busboy = require('connect-busboy'); //middleware for form/file upload
var path = require('path'); //used for file path
var fs = require('fs-extra'); //File System - for file manipulation
var mongoose = require('mongoose');
var mongoClient = require('mongodb').mongoClient;
var objectId = require('mongodb').ObjectId;
var app = express();
app.use(busboy());
app.use(express.static(path.join(__dirname, 'public')));
mongoose.Promise = global.Promise;
mongoose.connect('mongodb://localhost:27017/postname');
/* ==========================================================
Create a Route (/upload) to handle the Form submission
(handle POST requests to /upload)
Express v4 Route definition
============================================================ */
app.set('view engine','ejs');
app.use(express.static(__dirname + '/public'));
//You can import your schema like this
const Name = require('./name');
var compileSchema = mongoose.model('foods', nameSchema);
app.get('/', function(req, res, next) {
res.render('index',{'title': 'New post app'});
});
//I have changed your route since it seems to be clashing with the above
app.post('/save' ,function (req, res, next) {
var fstream;
req.pipe(req.busboy);
req.busboy.on('file', function (fieldname, file, filename) {
console.log("Uploading: " + filename);
//Path where image will be uploaded
fstream = fs.createWriteStream(__dirname + '/public/uploads/' + filename);
file.pipe(fstream);
var dirname = path.join(__dirname + '/public/uploads/' + filename);
//mongo save
fstream.on('close', function () {
//You can either save to mongodb after streaming closes or while it is streaming but in this case I will do it after.
console.log("Upload Finished of " + filename);
//where to go next
//Declare your schema object here
let name = new Name({
newfile:'Whatever you want to store here',
path: path
});
//Save your declared schema like this
name.save((err) => {
if(err) throw err;
console.log(`saved : ${name}`);
//When you redirect here, it will go to /profile route
res.redirect('/profile');
});
});
});
});
app.get('/profile', (req, res)=>{
//You must retrieve from mongodb your object here if this is where you want the object to be
//{} empty query will find all objects in the table
Name.find({}, (err, result) => {
if(err) throw err;
//after everything was found, send it to front end
res.render('profile',{
photo: req.result,
//Now your 'compileSchema' object is available at front end as 'result' object
result:result
});
});
});
var server = app.listen(3030, function() {
console.log('Listening on port %d', server.address().port);
});
name.js (create one schema js file for each table you will be working with)
let mongoose = require('mongoose');
let Schema = mongoose.Schema;
let compileSchema = new Schema({
newfile: Object,
path: String
});
let Compile = mongoose.model('Compiles', compileSchema);
module.exports = Compile;
Check first that you are receiving and streaming file correctly. If you are, it must work fine. Also, I don't know why you want to save a newfile:object field but all you really need to do is save the path to the image file then retrieve it where you need to use the image and use the path as the <img src='path'> Refer to the comments.
lately i started to play around with express.js the nodejs web framework. i'm making a simple form that send data to a express route.
I have a users.js route file and inside that there is a register route.
my user.js route file
router.post('/register', function(req, res, next) {
var name = req.body.name;
var email = req.body.email;
var username = req.body.username;
var password = req.body.password;
var passwordConfirm = req.body.passwordConfirm;
console.log(name);
my jade file which form is in it
form(method='post',action='/users/register',enctype='multipart/form-data')
.form-group
label Name
input.form-control(name='name',type='text',placeholder='Enter Name')
and go on ...
console.log retunrs undefiend.
my app.js . I used express generator to generate project, as you can see i have multer and bodyparser
var bodyParser = require('body-parser');
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var expressValidator = require('express-validator');
var cookieParser = require('cookie-parser');
var session = require('express-session');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var multer = require('multer');
var flash = require('connect-flash');
var mongo = require('mongodb');
var mongoose = require('mongoose');
var db = mongoose.connection;
var routes = require('./routes/index');
var users = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// multer config inja
var upload = multer({ dest: './uploads' });
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
// // handle express session
app.use(session({
secret: 'secret', //encryption key
saveUninitialized:true,
resave:true
}));
// // Passport
app.use(passport.initialize());
app.use(passport.session());
app.use(expressValidator({
errorFormatter: function(param, msg, value) {
var namespace = param.split('.')
, root = namespace.shift()
, formParam = root;
while(namespace.length) {
formParam += '[' + namespace.shift() + ']';
}
return {
param : formParam,
msg : msg,
value : value
};
}
}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
// flash messaging via connect-flash
app.use(flash());
app.use(function (req, res, next) {
res.locals.messages = require('express-messages')(req, res);
next();
});
app.use('/', routes);
app.use('/users', users);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
module.exports = app;
You have to configure an express middleware to parse the body of your HTTP request before hitting your /register route.
multipart/form-data enctype
This kind of type is often use for file upload. A library like Multer can be helpful for this use case.
I don't see a file to upload in your example. So you should consider using a simple enctype like application/x-www-form-urlencoded enctype (default) (see below).
If you still want to use form-data enctype without file upload, you can use a library like express-busboy (built on top of busboy).
var app = express();
var bb = require('express-busboy');
bb.extend(app);
// ...
router.post('/register', function(req, res, next) {
// req.body contains your fields.
// ...
application/x-www-form-urlencoded enctype (default)
If you configure your form to use the application/x-www-form-urlencoded enctype, it's a little bit easier to handle in your route.
body-parser can be use as a middleware too: https://github.com/expressjs/body-parser#bodyparserurlencodedoptions
var app = express();
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded());
// ...
router.post('/register', function(req, res, next) {
// ...
```
I am running into an issue where I am trying to run a POST request via Postman and I get a loading request for a long time and then a Could not get any response message. There are no errors that are appearing in terminal. Is it the way I am saving the POST? Specifically looking at my /blog route.
server.js
//Load express
var express = require('express');
var app = express();
var router = express.Router(); // get an instance of the router
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
// configure app to use bodyParser()
// get data from a POST method
app.use(bodyParser.urlencoded({ extended: true}));
app.use(bodyParser.json());
var port = process.env.PORT || 8080; // set the port
var blogDB = require('./config/blogDB.js');
var Blogpost = require('./app/models/blogModel');
app.set('view engine', 'ejs'); // set ejs as the view engine
app.use(express.static(__dirname + '/public')); // set the public directory
var routes = require('./app/routes');
// use routes.js
app.use(routes);
app.listen(port);
console.log('magic is happening on port' + port);
blogModel.js:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var BlogPostSchema = new Schema({
title : String,
body : String,
date_created : Date
});
module.exports = mongoose.model('Blogpost', BlogPostSchema);
routes.js:
var express = require('express');
var router = express.Router();
var blogDB = require('../config/blogDB.js');
var Blogpost = require('./models/blogModel.js');
//index
router.route('/')
.get(function(req, res) {
var drinks = [
{ name: 'Bloody Mary', drunkness: 3 },
{ name: 'Martini', drunkness: 5 },
{ name: 'Scotch', drunkness: 10}
];
var tagline = "Lets do this.";
res.render('pages/index', {
drinks: drinks,
tagline: tagline
});
});
//blog
router.route('/blog')
.get(function(req, res) {
res.send('This is the blog page');
})
.post(function(req, res) {
var blogpost = new Blogpost(); // create a new instance of a Blogpost model
blogpost.title = req.body.name; // set the blog title
blogpost.body = req.body.body; // set the blog content
blogpost.date_created = Date.now();
blogpost.save(function(err) {
if (err)
res.send(err);
res.json({ message: 'Blog created.' });
});
});
//about
router.get('/about', function(req, res) {
res.render('pages/about');
});
module.exports = router;
The issue was that I did not setup a user for my Mongo database. Basically it couldn't gain access to the user/pw to the database that I was using. Once I created a user matching the user/pw I included in my url, then I was able to get a successful post.