How to use nodejs RESTful api to query from multiple collections? - node.js

nodejs noobie here,
I have created nodejs RESTful api for fetching data from three different collections. Here is the article which helped me nodejs api in 10 minutes
After creating APIs, I am able to hit the APIs through postman and get data there. Now I wish to move on to next step of querying records from multiple collections
Server.js
var express = require('express'),
app = express(),
port = process.env.PORT ||3000,
mongoose = require('mongoose'),
menu = require('./app/api/bestseller_books/models/bestsellerBooksModel'),
admin = require('./app/api/admin/models/adminModel'),
test = require('./app/api/test/models/testModel'),
bodyParser = require('body-parser');
var Schema = mongoose.Schema;
var cors = require('cors');
// mongoose instance connection url connection
mongoose.Promise = global.Promise;
mongoose.connect('mongodb://localhost:27017/takebook', { useMongoClient: true });
/*mongoose.model('menu', new Schema({ title: String, id: Number }));*/
var menu = mongoose.model('bestseller_books');
var test = mongoose.model('test');
var admin = mongoose.model('admin');
var routes = require('./app/api/bestseller_books/routes/bestsellerBooksRoutes');
var routes2 = require('./app/api/admin/routes/adminRoutes');
var routes3 = require('./app/api/test/routes/testRoutes');
menu.find({}, function(err, data) { console.log(err, data.length); });
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(cors());
routes(app); //register the route
/*routes2(app);
routes3(app);*/
app.listen(port);
app.use(function(req, res) {
res.status(404).send({url: req.originalUrl + ' not found'})
});
console.log('RESTful API server started on: ' + port);
bestsellerbooks controller
'use strict';
var mongoose = require('mongoose'),
menu = mongoose.model('bestseller_books');
exports.list_all_menus = function(req, res) {
menu.find({}, function(err, menu) {
if (err)
res.send(err);
res.json(menu);
console.log(res);
});
};
exports.create_a_menu = function(req, res) {
var new_menu = new menu(req.body);
new_menu.save(function(err, menu) {
if (err)
res.send(err);
res.json(menu);
});
};
exports.read_a_menu = function(req, res) {
menu.findById(req.params.menuId, function(err, menu) {
if (err)
res.send(err);
res.json(menu);
});
};
exports.update_a_menu = function(req, res) {
menu.findOneAndUpdate({_id: req.params.menuId}, req.body, {new: true}, function(err, menu) {
if (err)
res.send(err);
res.json(menu);
});
};
exports.delete_a_menu = function(req, res) {
menu.remove({
_id: req.params.menuId
}, function(err, menu) {
if (err)
res.send(err);
res.json({ message: 'bestseller_books successfully deleted' });
});
};
My questions are :
Do I have to create new set of models, controllers and routes for
each API?
Looking at the server.js, is this the best practice of
setting up API routes?
What is the use of create_a_menu methods
mentioned in API controllers, if I have to hit API in this format:
app.controller('booklister', ['$http', function($http) {
var self = this;
$http.get('http://localhost:3000/bestseller_books')
.then(function(response)
{
/*$('.fa-refresh').hide();*/
self.items = response.data;
}, function(errResponse) {
/*$('.fa-refresh').show();*/
console.error('Service Error while fetching books' + errResponse);
});

Just create more from everything.
New model, new schema, new Bl layer, new route that take care for that new collection.
For example:
In yore dotsModel.js:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var DotsSchema = new Schema({
x: {
type: Number
},
y: {
type: Number
}
});
module.exports = mongoose.model('Dots', DotsSchema);
In youre dotsController.js:
var mongoose = require('mongoose'),
Dots = mongoose.model('Dots')
exports.get_all_dots = function (req, res) {
Dots.find({}, function (err, task) {
if (err)
res.send(err);
res.json(task);
});
};
And in your dotsRoutes.js:
module.exports = function(app) {
var todoList = require('../controllers/ dotsController.js:');
app.route('/dots')
.get(todoList.get_all_dots);
Note:
The article you read is short and he touch really briefly on each topic, it's highly recommended to take another course, much longer, and take the time to learn each part of your application, and what node capable of.

Related

mongoose required true req.body.name {}

If I set required to false, it will successfully create an object in the MongoDB database with one id. I suffer confusion sometimes, check my profile if you want. I think it's a little thing. If you need more info, just comment.
app.js
var express = require('express');
var bodyParser = require('body-parser');
var product = require('./routes/product'); // Imports routes for the products
var app = express();
var mongoose = require('mongoose'); // Set up mongoose connection
var dev_db_url = 'mongodb://localhost/Product';
var mongoDB = process.env.MONGODB_URI || dev_db_url;
mongoose.connect(mongoDB, {useNewUrlParser: true, useUnifiedTopology: true});
mongoose.Promise = global.Promise;
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'MongoDB connection error:'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use('/products', product);
var port = 3002;
app.listen(port, () => {
console.log('Server is up on port numbner ' + port);
});
model.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var ProductSchema = new Schema({
name: {type: String, required: true, max: 100},
price: {type: Number, required: true},
});
module.exports = mongoose.model('Product', ProductSchema);
controller.js
var Product = require('../models/product');
//Simple version, without validation or sanitation
exports.test = function (req, res) {
res.send('Greetings from the Test controller!');
};
exports.product_create = function (req, res, next) {
var product = new Product(
{
name: req.body.name,
bags: req.body.bags
}
);
console.log(JSON.stringify(req.body))
product.save(function (err) {
if (err) {
return next(err);
}
res.send('Bags Created successfully')
})
};
router.js
var express = require('express');
var router = express.Router();
// Require the controllers WHICH WE DID NOT CREATE YET!!
var product_controller = require('../controllers/product');
// a simple test url to check that all of our files are communicating correctly.
router.get('/test', product_controller.test);
router.post('/create', product_controller.product_create);
module.exports = router;
HTTP POST: http://localhost:3002/products/create?name=Jorge&price=20
ValidationError: Product validation failed: name: Path name is
required
Can you help?
Thanks!
💡 The reason why it's error, because your req.body.name is empty or null. Why it's null or empty or undefined? Because you're not add your data in your body, when you send create request.
You can see your Endpoint:
HTTP POST: http://localhost:3002/products/create?name=Jorge&price=20
It's not about req.body, it's a req.params. So you can use req.params.name and req.params.price.
🕵️‍♂️ So, If you're passing your data using parameres, your code will looks like this:
exports.product_create = function (req, res, next) {
var product = new Product(
{
name: req.params.name,
price: req.params.price
}
);
console.log(req.params);
product.save(function (err) {
if (err) {
return next(err);
}
res.send('Bags Created successfully')
})
};
If you want to use req.body, than add your json object tobody if you're using Postman.
🕵️‍♂️ You can see the image below: An example using postman to passing your data into body, before you send create request to your backend.
So, If You're passing your data from body, than your code will looks like this:
exports.product_create = function (req, res, next) {
var product = new Product(
{
name: req.body.name,
price: req.body.price
}
);
console.log(req.body);
product.save(function (err) {
if (err) {
return next(err);
}
res.send('Bags Created successfully')
})
};
I hope it's can help you.

How do I modularize my Node.js, express project?

I have created a API for different webpages with some CRUD functionality for POST, GET, etc. methods using Node.js, express and mongoose. I also have a big app.js file, where my routing logic and functions for CRUD methods reside.
So in the app.js file, I have to do the CRUD functionality and routing logic for every model in my models folder. This is quite much for on file, how can I separate the CRUD logic for my models, and the routing logic? So that it still works as normal without hosing my file?
I was thinking to separate the CRUD into a "controllers" folder and the routing into the "routes" folder, but I dont know how exactly, and what to require at what place..
My app.js looks like:
var express = require('express');
var app = express();
var bodyParser = require("body-parser");
var morgan = require("morgan");
var routes = require('./routes');
var cors = require('cors')
//configure app
app.use(morgan('dev')); //log requests to the console
//configure body parser
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
var port = process.env.PORT || 5000;
//DATABASE SETUP
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/DNZ'); //connect to uor datbaase
//Handle the connection event, get reference to database.
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function() {
console.log("DB connection alive");
});
//DNZ models live here
var FA = require('./models/DNZmodels/FA');
var FP = require('./models/DNZmodels/FP');
//ROUTES FOR OUR API
//=============================================================================
//create our router
var router = express.Router();
//middleware to use for all requests
router.use(function(req, res, next) {
// do logging
console.log('Something is happening.');
console.log('Today is:', Date())
next();
});
//test route to make sure everything is working (accessed at GET http://localhost:5000/DNZ/)
router.get('/', function(req, res) {
res.json({ message: 'Welcome to DNZ API!' });
});
//on routes that end in /FA
//----------------------------------------------------
router.route('/FA')
// create a FA (accessed at POST http://localhost:8080/DNZ/FA)
.post(function(req, res) {
//console.log(req.body);
//console.log(req.body.params);
//res.setHeader('Content-Type', 'application/json')
//res.send(JSON.stringify(req.body));
/*
var timestamp = req.body.Timestamp;
var prognostizierterBetriebswert = req.body.PrognostizierterBetriebswert;
var posFlexPot = req.body.posFlexPot;
var negFlexPot = req.body.negFlexPot;
var leistungsuntergrenze = req.body.Leistungsuntergrenze;
var leistungsobergrenze = req.body.Leistungsobergrenze;
var posGesEnergie = req.body.posGesEnergie;
var negGesEnergie = req.body.negGesEnergie;
var preissignal = req.body.Preissignal;
var dummy1 = req.body.Dummy1;
var dummy2 = req.body.Dummy2;
var dummy3 = req.body.Dummy3;
var fa = new FA({
Timestamp: timestamp,
Leistungsuntergrenze: leistungsuntergrenze,
Leistungsobergrenze:leistungsobergrenze,
PrognostizierterBetriebswert :prognostizierterBetriebswert,
posFlexPot: posFlexPot,
negFlexPot:negFlexPot,
posGesEnergie: posGesEnergie,
negGesEnergie: negGesEnergie,
Preissignal:preissignal,
Dummy1: dummy1,
Dummy2: dummy2,
Dummy3: dummy3
})
*/
//fa.name = req.body.name;
console.log("Erzeugen der Instanz FA..");
//console.log(Dummy1);
//res.send(JSON.stringify(timestamp));
// create a new instance of the FA model
var fa = new FA(req.body);
//SAVE the new instance
fa.save(function(err) {
if (err) {
console.log(err);
res.status(400);
res.send(err);
}
else {
console.log("Instanz FA in Datenbank erzeugt!");
res.status(200);
res.json({ message: 'FA-Instance created in datbase!' });
}
});
})
// get all the FAs (accessed at GET http://localhost:8080/DNZ/FA)
.get(function(req, res) {
FA.find(function(err, fas) {
if (err)
res.send(err);
res.json(fas);
});
});
//on routes that end in /FA/:FA_id
//----------------------------------------------------
router.route('/FA/:FA_id')
// get the bear with that id
.get(function(req, res) {
FA.findById(req.params.bear_id, function(err, fa) {
if (err)
res.send(err);
res.json(fa);
});
})
/*
* Athlete.
find().
where('sport').equals('Tennis').
where('age').gt(17).lt(50). //Additional where query
limit(5).
sort({ age: -1 }).
select('name age').
exec(callback);
*/
// update the bear with this id
.put(function(req, res) {
FA.findById(req.params.FA_id, function(err, fa) {
if (err)
res.send(fa);
//bear.name = req.body.name;
/*
FA.save(function(err) {
if (err)
res.send(err);
res.json({ message: 'FA updated!' });
});
*/
});
});
/*
// delete the bear with this id
.delete(function(req, res) {
FA.remove({
_id: req.params.bear_id
}, function(err, FA) {
if (err)
res.send(err);
res.json({ message: 'Successfully deleted' });
});
});
*/
//*************************************************************************
//CREATE FP ROUTE
//*************************************************************************
router.route('/FP')
// create a FA (accessed at POST http://localhost:8080/DNZ/FP)
.post(function(req, res) {
//res.setHeader('Content-Type', 'application/json')
console.log("Erzeugen der Instanz FP..");
// create a new instance of the FP model
var fp = new FP(req.body);
//SAVE the new instance
fp.save(function(err) {
if (err) {
console.log(err);
res.status(400);
res.send(err);
}
else {
console.log("Instanz FP in Datenbank erzeugt!");
res.status(200);
res.json({ message: 'FP-Instance created in datbase!' });
}
});
})
// get all the FAs (accessed at GET http://localhost:8080/DNZ/FA)
.get(function(req, res) {
FP.find(function(err, fps) {
if (err) {
console.log(err);
res.status(400);
res.send(err);
}
else {
//res.send("Willkommen auf /FP");
res.json(fps);
}
});
});
//REGISTER OUR ROUTES -------------------------------and listen to requests
app.use('/DNZ', router);
//START THE SERVER
//=============================================================================
// set static directories
app.use(express.static('./dist'));
app.use(cors());
// Define Routes
var index = require('./routes/index');
var users = require('./routes/users');
//Set up routes
routes.init(app)
//run
app.listen(port);
console.log('Listen on port: ' + port);
console.log('Server started, Listening on port ', port);
This is primarily opinion based, but I had the same thing a while back and developed a way to extract route/model logic from the main file, using the module require-dir
In my app.js
/**
* Process ALL routes from routes dir utilising require-dir
*
* Allows us to include an entire directory, without replicating
* code, creating similar routes on a per end-point basis. This
* nicely keeps all end-point routes separate.
*/
var routes = requireDir('./routes');
for(var x in routes) {
application.use('/', routes[x]); // here, application is your express server instance
}
Then create a directory called routes and add whatever, for instance routes/branding.js:
var expressFramework = require('express');
var Branding = require('../models/branding');
var responseHelper = require('../shared/responseHelper');
var responseStatusCodes = require('../shared/responseStatusCodes');
var responseMessages = require('../shared/responseMessages');
var queryHelper = require('../shared/queryHelper');
var routerObject = expressFramework.Router();
var branding = new Branding();
var responsehelper = new responseHelper();
var queryhelper = new queryHelper();
/**
* Endpoint /branding/{chain_id}/{site_id}
*/
routerObject.get('/branding/:chain_id/:site_id', function(req, res, next) {
var requiredFields = [
{
chain_id: true, where: 'path'
},
{
site_id: true, where: 'path'
}
];
if (!queryhelper.authenticateToken(req.headers.authorization)) {
responsehelper.sendResponse(res, responseStatusCodes.STATUS_UNAUTHORISED,
responseMessages.RESPONSE_AUTHENTICATION_FAILED);
return;
}
if (!queryhelper.validateQuery(req, requiredFields)) {
responsehelper.sendResponse(res, responseStatusCodes.STATUS_INVALID_QUERY_PARAMS,
responseMessages.RESPONSE_INVALID_QUERY_PARAMS);
return;
}
branding.getBranding(req, function(err, results, pagination) {
if (err) return next(err);
if (results.length >= 1) {
responsehelper.sendResponse(res, responseStatusCodes.STATUS_OK, results);
} else {
responsehelper.sendResponse(res, responseStatusCodes.STATUS_NOT_FOUND,
responseMessages.RESPONSE_NO_RECORDS_FOUND);
}
});
});
module.exports = routerObject;
The key point here, is that you eventually export the express Router object, which your application, can 'use'. You'll also notice, that branding uses an include var Branding = require('../models/branding'); - This contains all the logic, whereas the route contains the end point definitions only, a snippet:
var Promise = require('bluebird');
var db = require('../shared/db');
var queryHelper = require('../shared/queryHelper');
var schemas = require('../schemas/schemas');
var _ = require('lodash');
var serverSettings = require('../shared/coreServerSettings');
// Create new instance of mysql module
var connection = new db();
var queryhelper = new queryHelper();
var queryAndWait = Promise.promisify(connection.query);
// Branding Object
var Branding = function(data) {
this.data = data;
};
Branding.prototype.data = {};
/**
* Branding methods
*/
Branding.prototype.getBranding = function(req, callback) {
var params = [];
var queryFoundRows = `select FOUND_ROWS() as total`;
var query = `select
id
from
company
where
1=1
and chain_id=?`;
params.push(req.params.chain_id);
queryAndWait(query + '; ' + queryFoundRows, params).then(function(result) {
return Promise.map(result[0], function(row) {
var params = [];
var query = `select
*
from
location
where
1=1
and company_id=?
and site_id=?`;
params.push(row.id);
params.push(req.params.site_id);
return queryAndWait(query, params).then(function(result) {
return result[0];
});
}).then(function(payload) {
callback(null, payload);
}).catch(function(err) {
callback(err, null, null);
});
});
};
module.exports = Branding;
May not be exactly what you're after, but should provide a good start point. Good luck!
This topic is subjective however - it is important to take a standard and stick to it. The way I handled this was by creating a subfolder with a module (using module.exports) and an init function that constructs the express app.
For every route I have another module that has an init function which accepts the express application as a parameter and then adds the routes in there.
Main code file:
var Api = require('./API/index.js');
File /API/Index.js:
var express = require('express');
/* Instantiations */
var app = express();
module.exports = {
...
apply();
...
}
var route1 = require('./Routes/route1.js');
var route2 = require('./Routes/route2.js');
/* all additional routes */
var Routes = [route1,route2,...]
function apply(){
for(var i=0;i<Routes.length;i++){
Routes[i].init(app);
}
}
Then in API/Routes/route1.js and API/Routes/route2.js...
module.exports = {
init: function(app){
/* add your route logic here */
}
}
The benefits of this approach in my experience is that you can optionally choose to add or remove routes as needed and it provides a readable route-path via the file system which is handy in most modern text editors.

Creating MongoDB connection with mongoose

I am desperately trying to create a connection with mongoDB with the MEAN stack, using mongoose.
My MongoDB instance (mongod) is running and I can use mongo.exe and tested it by inserting some documents, it worked fine. But I have problems to create a connection to MongoDB with mongoose, and inserting a document with the .save() method does not work either...
I first wanted to try my POST method, created a function and tested it by creating some values in POSTMAN. But no documents were inserted in my MongoDB datbase..
This is my app.js file:
var express = require('express');
var app = express();
var bodyParser = require("body-parser");
var morgan = require("morgan");
//var routes = require('./routes');
//var cors = require('cors')
//configure app
app.use(morgan('dev')); //log requests to the console
//configure body parser
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
var port = process.env.PORT || 5000;
//DATABASE SETUP
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/DNZ'); //connect to uor datbaase
//Handle the connection event
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function() {
console.log("DB connection alive");
});
//DNZ models live here
var FA = require('./models/DNZmodels/FA');
//ROUTES FOR OUR API
//=============================================================================
//create our router
var router = express.Router();
//middleware to use for all requests
router.use(function(req, res, next) {
// do logging
console.log('Something is happening.');
console.log('Today is:', Date())
next();
});
//test route to make sure everything is working (accessed at GET http://localhost:5000/DNZ/)
router.get('/', function(req, res) {
res.json({ message: 'Welcome to DNZ API!' });
});
//on routes that end in /FA
//----------------------------------------------------
router.route('/FA')
// create a FA (accessed at POST http://localhost:8080/DNZ/FA)
.post(function(req, res) {
//console.log(req.body);
//console.log(req.body.params);
//res.setHeader('Content-Type', 'application/json')
res.send(JSON.stringify(req.body));
/*
var timestamp = req.body.Timestamp;
var prognostizierterBetriebswert = req.body.PrognostizierterBetriebswert;
var posFlexPot = req.body.posFlexPot;
var negFlexPot = req.body.negFlexPot;
var leistungsuntergrenze = req.body.Leistungsuntergrenze;
var leistungsobergrenze = req.body.Leistungsobergrenze;
var posGesEnergie = req.body.posGesEnergie;
var negGesEnergie = req.body.negGesEnergie;
var preissignal = req.body.Preissignal;
var dummy1 = req.body.Dummy1;
var dummy2 = req.body.Dummy2;
var dummy3 = req.body.Dummy3;
*/
var fa = new FA();
fa.name = req.body.name;
console.log("Hier erscheint var fa:", fa);
//console.log(Dummy1);
//res.send(JSON.stringify(timestamp));
// create a new instance of the FA model
/*
var fa = new FA({
Timestamp: timestamp,
Leistungsuntergrenze: leistungsuntergrenze,
Leistungsobergrenze:leistungsobergrenze,
PrognostizierterBetriebswert :prognostizierterBetriebswert,
posFlexPot: posFlexPot,
negFlexPot:negFlexPot,
posGesEnergie: posGesEnergie,
negGesEnergie: negGesEnergie,
Preissignal:preissignal,
Dummy1: dummy1,
Dummy2: dummy2,
Dummy3: dummy3
})
*/
//SAVE the new instance
fa.save(function(err) {
if (err) {
console.log(err);
res.status(400);
res.send(err);
}
else {
console.log("debug");
res.status(200);
res.json({ message: 'FA created!' });
}
});
})
// get all the FAs (accessed at GET http://localhost:8080/DNZ/FA)
.get(function(req, res) {
FA.find(function(err, fas) {
if (err)
res.send(err);
res.json(fas);
});
});
//on routes that end in /FA/:FA_id
//----------------------------------------------------
router.route('/FA/:FA_id')
// get the bear with that id
.get(function(req, res) {
FA.findById(req.params.bear_id, function(err, fa) {
if (err)
res.send(err);
res.json(fa);
});
})
// update the bear with this id
.put(function(req, res) {
FA.findById(req.params.FA_id, function(err, fa) {
if (err)
res.send(fa);
//bear.name = req.body.name;
/*
FA.save(function(err) {
if (err)
res.send(err);
res.json({ message: 'FA updated!' });
});
*/
});
})
/*
// delete the bear with this id
.delete(function(req, res) {
FA.remove({
_id: req.params.bear_id
}, function(err, FA) {
if (err)
res.send(err);
res.json({ message: 'Successfully deleted' });
});
});
*/
//REGISTER OUR ROUTES -------------------------------
app.use('/DNZ', router);
//START THE SERVER
//=============================================================================
app.listen(port);
console.log('Magic happens on port ' + port);
/*
// set static directories
app.use(express.static('./dist'));
app.use(cors());
// Define Routes
var index = require('./routes/index');
var users = require('./routes/users');
//Set up routes
routes.init(app)
//run
app.listen(port);*/
console.log('Server started, Listening on port ', port);
I used the "template" from the Bear tutorial:
https://scotch.io/tutorials/build-a-restful-api-using-node-and-express-4
the problem here is already, that there is no message: "DB connection alive". However, in the bear tutorial (whose code I used here), the DB connection is built and I can insert bear documents in the database. However, here it does not work...
and this is my FA Schema model from FA.js:
var mongoose = require("mongoose");
var Schema = mongoose.Schema;
var FASchema = new Schema({
Timestamp: Date,
PrognostizierterBetriebswert: Number,
posFlexPot: Number,
negFlexPot: Number,
Leistungsuntergrenze: Number,
Leistungsobergrenze: Number,
posGesEnergie: Number,
negGesEnergie: Number,
Preissignal: Number,
Dummy1: Schema.Types.Mixed,
Dummy2: Schema.Types.Mixed,
Dummy3: Schema.Types.Mixed
//same: Dummy: {}
});
//var FASchema = new Schema({name: String});
module.exports = mongoose.model("FA", FASchema, 'FA');
console.log("FA wird ausgeführt!");
Anybody got an idea why there is no DB connection created?
when I test your code , the Error (Can't set headers after they are sent) was thrown. you can delete res.send(JSON.stringify(req.body)); and restart service

Mongoose or MongoDB for Schema definition?

Mongoose is used to define a schema. right?
Is it is possible to create a schema with mongoDB through mongo Shell ? like
eg: name:String
MongoDB doesn't support schema. It's a schemaless document based DB.
Mongoose is an ODM(Object Document Mapper) that helps to interact with MongoDB via schema, plus it also support validations & hooks.
Basically mongodb is schema less database we cant able to create schema directly in mongodb. Using mongoose we can able to create a schema. Simple CRUD operation using mongoose, for more info ref this link
package.json
{
"name": "product-api",
"main": "server.js",
"dependencies": {
"express": "~4.0.0",
"body-parser": "~1.0.1",
"cors": "2.8.1",
"mongoose": "~3.6.13"
}
}
product.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var ProductSchema = new Schema({
title: String,
price: Number,
instock : Boolean,
photo : String ,
});
module.exports = mongoose.model('Product', ProductSchema);
// module.exports = mongoose.model('Product', ProductSchema,'optiponally pass schema name ');
server.js
var express = require('express');
var bodyParser = require('body-parser');
var cors = require('cors');
var app = express();
var mongoose = require('mongoose');
var product = require('./product');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
var port = process.env.PORT || 8090;
var router = express.Router();
mongoose.connect('mongodb://localhost:27017/products');
// Middle Route
router.use(function (req, res, next) {
// do logging
// do authentication
console.log('Logging of request will be done here');
next(); // make sure we go to the next routes and don't stop here
});
router.route('/products').post(function (req, res) {
console.log("in add");
var p = new product();
p.title = req.body.title;
p.price = req.body.price;
p.instock = req.body.instock;
p.photo = req.body.photo;
p.save(function (err) {
if (err) {
res.send(err);
}
console.log("added");
res.send({ message: 'Product Created !' })
})
});
router.route('/products').get(function (req, res) {
product.find(function (err, products) {
if (err) {
res.send(err);
}
res.send(products);
});
});
router.route('/products/:product_id').get(function (req, res) {
product.findById(req.params.product_id, function (err, prod) {
if (err)
res.send(err);
res.json(prod);
});
});
router.route('/products/:product_id').put(function (req, res) {
product.findById(req.params.product_id, function (err, prod) {
if (err) {
res.send(err);
}
prod.title = req.body.title;
prod.price = req.body.price;
prod.instock = req.body.instock;
prod.photo = req.body.photo;
prod.save(function (err) {
if (err)
res.send(err);
res.json({ message: 'Product updated!' });
});
});
});
router.route('/products/:product_id').delete(function (req, res) {
product.remove({ _id: req.param.product_id }, function (err, prod) {
if (err) {
res.send(err);
}
res.json({ message: 'Successfully deleted' });
})
});
app.use(cors());
app.use('/api', router);
app.listen(port);
console.log('REST API is runnning at ' + port);
Mongoose helps to interact with MongoDB in terms of Object/Model so that programmer doesn't need to understand the remember the statements of MongoDB.
Also, Mongoose provides lot of methods of CRUD Operations to better understanding of DB Operations.
You can check examples here
https://developer.mozilla.org/en-US/docs/Learn/Server-side/Express_Nodejs/mongoose
http://mongoosejs.com/docs/
Mongoose has its benefits of validation and schema configurations but it has its cons of latency and some problems with high/mid scale applications.
it's always the best thing IMHO, to use the native mongodb package.
regarding schema, you can create your own "schema" as a json file and write ur own validations for mandatory or valid attributes.
it's faster, with no third party packages and more reliable.

Validation failed nodejs required field

I am creating creating a bookstore demo app in Node.js. I have ran into a little situation with the POST request for creating a genre. I've setup so the name of the genre must be required if not don't insert it to the database. But when I use Postman to POST to the url localhost:3000/api/genres with the JSON
{
"name": "TEST"
}
It throws an error
{
"error": "Genre validation failed"
}
When I remove the required field in the genreSchema it works but the name of the genre doesn't appear. Here is my code
Code:
genre.js
var mongoose = require("mongoose");
// Create a schema for genre
var Schema = mongoose.Schema;
var genreSchema = Schema({
name:{
type: String,
required: true
},
create_date:{
type: Date,
default: Date.now
}
});
var Genre = module.exports = mongoose.model("Genre", genreSchema);
// Methods
// get genres
module.exports.getGenres = function(callback, limit) {
Genre.find(callback).limit(limit);
};
// add a new genre
// TODO: Not working in Postman ValidationError
module.exports.addGenre = function(genre, callback) {
Genre.create(genre, callback);
};
app.js
var express = require("express");
var app = express();
var bodyParser = require("body-parser");
var mongoose = require("mongoose");
var Genre = require('./models/genre');
var Book = require('./models/book');
// Connect to mongoose
mongoose.connect("mongodb://localhost/bookstore");
var db = mongoose.connection;
app.get("/", function(req, res){
res.json({ error: "Please use /api/books or /api/genres" });
});
// GET /api/genres
app.get('/api/genres', function(req, res){
Genre.getGenres(function(err, genres){
if(err) {
res.json({error: err.message})
}
res.json(genres);
});
});
app.post('/api/genres', function(req, res){
var genre = req.body;
Genre.addGenre(genre, function(err, genre){
if(err) {
res.json({
error: err.message
})
}
res.json(genre);
});
});
// GET /api/books
app.get('/api/books', function(req, res){
Book.getBooks(function(err, books){
if(err) {
res.json({error: err.stack})
}
res.json(books);
});
});
// GET /api/book/:id
app.get('/api/book/:_id', function(req, res){
Book.getBookById(req.params._id, function(err, book){
if(err) {
res.json({error: err.message})
}
res.json(book);
});
});
app.listen(3000, function(){
console.log("Running on port 3000!")
});
Have you tried console.log(req.body); inside your post route? I don't think you've setup body-parser as middleware so req.body is coming in empty and therefore not sending anything to your Genre.addGenre method.

Resources