Oh man, this API project is a real huge pain. I got all of these endpoints working yesterday, but as soon as I stared trying to add data to a collection in the database (via Mongo shell), all of a sudden my requests are hanging up. Here is my server:
var express = require('express'),
app = express(),
port = process.env.PORT || 3000;
mongoose = require('mongoose'),
Character = require('./api/models/characterListModels'),
bodyParser = require('body-parser');
mongoose.Promise = global.Promise;
mongoose.connect({ useNewUrlParser: true }, 'mongodb://127.0.0.1:27017/streetfighterdb');
app.use(bodyParser.urlencoded({ extended: true}));
app.use(bodyParser.json());
var routes = require('./api/routes/characterListRoutes')
routes(app);
app.listen(port);
console.log('Street Fighter RESTful API server started on: ' + port);
Here is my controller
'use strict';
var mongoose = require('mongoose'),
Character = mongoose.model('Characters')
exports.list_all_characters = function (req, res) {
Character.find({}, function (error, character) {
if (error) {
res.send(error);
} else {
res.json(character)
}
})
}
exports.create_a_character = function (req, res) {
var new_character = new Character(req.body);
new_character.save(function (error, character) {
if (error) {
res.send(error);
}
res.json(character);
});
}
exports.get_a_character = function (req, res) {
Character.findById(req.params.characterId, function (error, character) {
if (error) {
res.send(error);
}
res.json(character);
});
}
exports.update_a_character = function (req, res) {
Character.findByIdAndUpdate({
_id: req.params.characterId
}, req.body, {
new: true
}, function (error, character) {
if (error) {
res.send(error);
}
res.json(character);
});
}
exports.delete_a_character = function (req, res) {
Character.deleteOne({
_id: req.params.characterId
}, function (error, character) {
if (error) {
res.send(error);
}
if (!error) {
res.json('Character Successfully Deleted');
}
})
}
Here is my router
'use strict';
module.exports = function(app) {
var characterList = require('../controllers/characterListController');
app.route('/characters')
.get(characterList.list_all_characters)
.post(characterList.create_a_character);
app.route('/characters/:characterId')
.get(characterList.get_a_character)
.put(characterList.update_a_character)
.delete(characterList.delete_a_character);
};
Here is my Model
'use strict';
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var characterSchema = new Schema({
name: {
type: String,
required: true,
}
})
module.exports = mongoose.model('Characters', characterSchema);
Now I have tried a few things.
Removed the specific response and just added a generic res.send('success') and it worked.
I also replaced the {} in the Character.find() method with a [] and it worked (responded with an empty object). For some reason though, none of the other endpoints return responses.
Added a console.log(res) and a console.log(req) and got the logs in the console.
What is going on here? Help!!
Referenced by mongoose offical docs
mongoose.connect('mongodb://username:password#host:port/database?options...', {useNewUrlParser: true});
You are passing the options as first argument, please replace it as offical docs example.
Ok, this is ridiculous, but it turns out that passing the { useNewUrlParser: true } broke it.
Related
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.
This is indeed a duplicate question however there is no answer.
The problem is that when I save a new record with mongoose through a post request, all that's saved is something like this:
{ "_id" : ObjectId("5d11590975c82f216eaa4712"), "__v" : 0 }
I am following this tutorial so the code should work fine, but regardless here it is:
the mongoose schema:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
let Todo = new Schema({
todo_description: {
type: String
},
todo_responsible: {
type: String
},
todo_priority: {
type: String
},
todo_completed: {
type: Boolean
}
});
module.exports = mongoose.model('Todo', Todo);
the code:
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const cors = require('cors');
const mongoose = require('mongoose');
const todoRoutes = express.Router();
const PORT = 4000;
let Todo = require('./todo.model');
app.use(cors());
app.use(bodyParser.json());
mongoose.connect('mongodb://127.0.0.1:27017/todos', { useNewUrlParser: true });
const connection = mongoose.connection;
connection.once('open', function() {
console.log("MongoDB database connection established successfully");
})
todoRoutes.route('/').get(function(req, res) {
Todo.find(function(err, todos) {
if (err) {
console.log(err);
} else {
res.json(todos);
}
});
});
todoRoutes.route('/:id').get(function(req, res) {
let id = req.params.id;
Todo.findById(id, function(err, todo) {
res.json(todo);
});
});
todoRoutes.route('/update/:id').post(function(req, res) {
Todo.findById(req.params.id, function(err, todo) {
if (!todo)
res.status(404).send("data is not found");
else
todo.todo_description = req.body.todo_description;
todo.todo_responsible = req.body.todo_responsible;
todo.todo_priority = req.body.todo_priority;
todo.todo_completed = req.body.todo_completed;
todo.save().then(todo => {
res.json('Todo updated!');
})
.catch(err => {
res.status(400).send("Update not possible");
});
});
});
todoRoutes.route('/add').post(function(req, res) {
let todo = new Todo(req.body);
todo.save()
.then(todo => {
res.status(200).json({'todo': 'todo added successfully'});
})
.catch(err => {
res.status(400).send('adding new todo failed');
});
});
app.use('/todos', todoRoutes);
app.listen(PORT, function() {
console.log("Server is running on Port: " + PORT);
});
the post request:
the get request:
To confirm here's the output in mongodb:
the problem is that the body needs to be Json(application/json) instead of Text
Everything is fine with your code
Just add this line to your todo.model.js
module.exports = mongoose.model('Todo', Todo);
1:
Edit:
I also had this problem and I fixed Content-type: application / json and it worked
make sure you added app.use(express.json()) to your server.js file.
Try using body-parser and use:
app.use(bodyParser.json());
In the app.js file
I'm new at using back-end code.
I'm trying to Insert basic line into MongoDB online DB.
These are my files:
server.js:
const express = require('express');
const MongoClient = require('mongodb').MongoClient;
const bodyParser = require('body-parser');
const app = express();
var db = require('./config/db');
const port = 8000;
app.use(bodyParser.urlencoded({ extended: true }));
MongoClient.connect(db.url, (err, database) => {
if (err) return console.log(err);
db = database.db('note-api');
require('./app/routes')(app, db);
require('./app/routes')(app, database);
app.listen(port, () => {
console.log('We are live on ' + port);
});
})
note_routes.js:
module.exports = function (app, db) {
// const collection =
app.post('/notes', (req, res) => {
const note = { text: req.body.body, title: req.body.title };
db.collection('notes').insert(note, (err, result) => {
if (err) {
res.send({ 'error': err });
} else {
res.send(result.ops[0]);
}
});
});
};
db.js:
module.exports = {
url: "mongodb://laelav:laelav1#ds227594.mlab.com:27594/getremp"
};
Whenever i try using POST and wish to update the online DB - I get an unauthorized error:
unauthorized error
Then I added this line in note_routes.js:
db.grantRolesToUser("laelav", [{ role: "readWrite", db: "getremp" }]);
And got the following "TypeError: db.grantRolesToUser is not a function":
not a function error
Please help!
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.
My code as follows. Open localhost/users/,brower return
{"_id":"55519446e063d4c409f93f00","username":"justnode","__v":0}
but when I open mongo shell and input: use student and db.student.find(),I can't find anything. My MongoDB version is 3.0.1 and nodejs version is 0.12.2, OS is Centos 6.4
var express = require('express');
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var app = express();
mongoose.connect('mongodb://localhost/student', function (error) {
if (error) {
console.log(error);
}
});
var Schema = mongoose.Schema;
var UserSchema = new Schema({
username: {type: String, unique: true}
});
var UserModel = mongoose.model('UserModel', UserSchema);
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
/*
post content as follows
{
"username": "justnode"
}
*/
app.post('/users/create', function (req, res) {
console.log("in /users/create");
var userModelJson = req.body;
var userModel = new UserModel(userModelJson);
userModel.save(function(error) {
if(error) {
console.log(error);
return res.json({msg: "error"});
}
console.log("user created: " + userModel.username);
res.json(userModel);
});
});
/*
open localhost/users/ brower return {"_id":"55519446e063d4c409f93f00","username":"justnode","__v":0}]
but when I open mongo client: db.student.find() i can't find anything
*/
app.get('/users', function (req, res) {
UserModel.find({}, function (err, docs) {
res.json(docs);
});
});
var serverApp = app.listen(80, function () {
console.log('Express server listening on port ' + serverApp.address().port);
});
Change database(student), schema(UserSchema) and model(UserModel)'s name and try it again. My case, after changing the variable's name and restart, it works. (I've no idea why, maybe mongoose or mongo shell has some bug?)