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
Related
Mongo save callback is not triggering, but the document is getting saved in the db, Heres my code:
MongoDb Version : 6.0.1
Mongoose Version : 6.8.2
The call back not returning anything, but the documents are getting saved without any issues, why the call back is not triggering?
const express = require("express");
const app = express();
const bodyParser = require("body-parser");
const mongoose = require("mongoose");
const url = 'mongodb://127.0.0.1:27017/musicapp';
const cors = require('cors');
var jquery = require('jquery');
//Mongodb
mongoose.connect(url, { useNewUrlParser: true });
mongoose.set('strictQuery', true);
var conn = mongoose.connection;
conn.on('connected', function () {
console.log("Database Connected");
})
var artistSchema = new mongoose.Schema({
artistName: String,
artistDob: String,
artistBio: String
})
const artists = mongoose.model("artist", artistSchema);
function addArtist(aName, aDOB, aBIO) {
const newArtist = new artists({
artistName: aName,
artistDob: aDOB,
artistBio: aBIO
})
newArtist.save((err, data, numAffected) => {
if (!err) {
return true;
}
else {
return false;
}
});
}
//MongoDb
app.get("/", (req, res) => {
res.sendFile(__dirname + "/index.html")
})
app.post("/addsongs", cors(), (req, res) => {
console.log("Add songs");
})
app.post("/addartist", cors(), (req, res) => {
var artistName = req.body.modalartistname;
var artistDOB = req.body.modalartistdob;
var artistBio = req.body.modalartistbio;
var addedArtist = addArtist(artistName, artistDOB, artistBio);
if (addedArtist) {
res.sendStatus(200);
}
else {
console.log("Failure")
res.sendStatus(400);
}
//console.log("Artist Added Sucessfully");
})
app.listen(3000, function () {
console.log("The Server is up and running");
})
I'm going to develop API using Node Express & Mongo.I have manually entered data to mongo db like below and when i try to get data from the db it shows me empty in postman.Here i have paste my project code for easy to figure out.
In the controller returned empty results.
my project structure looks like this
db.config.json
module.exports = {
//url: "mongodb://localhost:27017/TestDb"
url: "mongodb://localhost:27017/Users"
};
server.js
const express = require("express");
const cors = require("cors");
const app = express();
var corsOptions = {
origin: "http://localhost:8081"
};
app.use(cors(corsOptions));
// parse requests of content-type - application/json
app.use(express.json());
// parse requests of content-type - application/x-www-form-urlencoded
app.use(express.urlencoded({ extended: true }));
// simple route
app.get("/", (req, res) => {
res.json({ message: "Welcome to Shopping List." });
});
require("./app/routes/user.routes")(app);
// set port, listen for requests
const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}.`);
});
const db = require("./app/models");
db.mongoose
.connect(db.url, {
useNewUrlParser: true,
useUnifiedTopology: true
})
.then(() => {
console.log("Connected to the database!");
})
.catch(err => {
console.log("Cannot connect to the database!", err);
process.exit();
});
index.js
const dbConfig = require("../config/db.config.js");
const mongoose = require("mongoose");
mongoose.Promise = global.Promise;
const db = {};
db.mongoose = mongoose;
db.url = dbConfig.url;
db.users = require("./user.model.js")(mongoose);
console.log(db.url);
module.exports = db;
user.contoller.js
const db = require("../models");
const User = db.users;
// Retrieve all Tutorials from the database.
exports.findAll = (req, res) => {
User.find({ isAdmin: false })
.then(data => {
console.log("datanew"+data); // <-- Empty returns here.. []
res.send(data);
})
.catch(err => {
res.status(500).send({
message:
err.message || "Some error occurred while retrieving user."
});
});
};
user.model.js
module.exports = mongoose => {
var schema = mongoose.Schema(
{
firstName: String,
lastName: String,
password: String,
email:String,
isAdmin:Boolean
},
{ timestamps: true }
);
schema.method("toJSON", function() {
const { __v, _id, ...object } = this.toObject();
object.id = _id;
return object;
});
const User = mongoose.model("user", schema);
return User;
};
user.route.js
module.exports = app => {
const users = require("../controllers/user.controller.js");
var router = require("express").Router();
// Retrieve all Tutorials
router.get("/", users.findAll);
app.use('/api/users', router);
};
It appears you manually created your MongoDB collection. Users must be in small letters so from the MongoDB interface, change Users => users and you'll be set.
Also your DB connection uri should be:
module.exports = {
url: "mongodb://localhost:27017/TestDb"
};
TestDB is the database while users is the collection. Your uri must point to a db that your code will query collections in.
Your User Model
This is just a slight change but you want to keep your code consistent. User should all be in capitalize form. MongoDB is smart to user plural and small caps automatically in the db.
module.exports = mongoose => {
var schema = mongoose.Schema(
{
firstName: String,
lastName: String,
password: String,
email:String,
isAdmin:Boolean
},
{ timestamps: true }
);
schema.method("toJSON", function() {
const { __v, _id, ...object } = this.toObject();
object.id = _id;
return object;
});
const User = mongoose.model("User", schema);
return User;
};
// Actually you can remove
index.js
db.config.js files
// *********
add in server.js
const express = require('express')
const mongoose = require('monggose')
const app = express()
mongoose.connect('mongodb://localhost/TestDb');
I am using node and express server to run the mongoDb. For connection and schema I am using mongoose. i successfully connect the database and able to post the data by using postman but problem is it does not show the expected query. Mongodb returns me only the id not the query which is name and description
Here is models
const mongoose = require("mongoose");
const { Schema } = mongoose;
const form = new Schema(
{
name: { type: String },
description: { type: String }
},
{
timestamps: true
}
);
const formSubmit = mongoose.model("formSubmit", form);
module.exports = formSubmit;
This is my express server
const express = require("express");
const port = 5000;
const cors = require("cors");
const morgan = require("morgan");
const app = express();
const formSubmit = require("./models");
const mongoose = require("mongoose");
app.use(cors());
app.use(morgan("dev"));
mongoose
.connect(
"url",
{
useUnifiedTopology: true,
useNewUrlParser: true
}
)
.then(() => console.log("DB Connected!"))
.catch(err => {
console.log(err);
});
//get method
app.get("/show", async (req, res) => {
try {
const entrries = await formSubmit.find();
res.json(entrries);
} catch (error) {
console.log(error);
}
});
//post method
app.post("/post", async (req, res, next) => {
try {
const logs = new formSubmit(req.body);
const entry = await logs.save();
res.json(entry);
} catch (error) {
if (error.name === "ValidationError") {
res.status(422);
}
next(error);
}
});
app.listen(port, () => {
console.log(`Server is running port ${port}`);
});
I think the problem is you don't correctly save the documents to the collection, so when you retrieve them only _id fields display.
To be able to read request body, you need to add express.json() middleware to your server.js.
app.use(express.json());
On localhost:5000/posts my data is successfully showing but if I do the same thing in Heroku: https://rest-in-peep.herokuapp.com/posts I get an application error. https://rest-in-peep.herokuapp.com/ works fine and I deployed it through Heroku GIT. I made sure to config my environmental vars in Heroku and added a Procfile but I am still getting this application error. I've been trying all day to figure this out but what I expect to happen is if I type in https://rest-in-peep.herokuapp.com/posts, I will get all the data that is being stored on my MongoDB database.
app.js file
const http = require("http");
const express = require("express");
const mongoose = require("mongoose");
const bodyParser = require("body-parser");
const cors = require("cors");
require("dotenv/config");
const app = express();
const server = http.createServer(app);
//Middlewares
app.use(cors());
app.use(bodyParser.json());
//Import Routes
const postsRoute = require("./routes/posts");
app.use("/posts", postsRoute);
//ROUTES
app.get("/", (req, res) => {
res.send("We are on home");
});
//Connect to DB
mongoose.connect(
process.env.DB_CONNECTION,
{ useNewUrlParser: true },
() => console.log("connected to MongoDB")
);
//How do we start listening to the server
server.listen(process.env.PORT || 5000, () => {
console.log("App now running on PORT");
});
routes>
posts.js
const express = require("express");
const Post = require("../models/Posts");
const router = express.Router();
//GETS BACK ALL THE POSTS
router.get("/", async (req, res) => {
try {
const posts = await Post.find();
res.json(posts);
} catch (err) {
res.json({ message: err });
}
});
//SUBMITS A POST
router.post("/", async (req, res) => {
console.log(req);
const post = new Post({
quote: req.body.quote
});
try {
const savedPost = await post.save();
res.json(savedPost);
} catch (err) {
res.json({ message: err });
}
});
//SPECIFIC POST
router.get("/:postId", async (req, res) => {
try {
const post = await Post.findById(req.params.postId);
res.json(post);
} catch (err) {
res.json({ message: err });
}
});
//Delete Post
router.delete("/:postId", async (req, res) => {
try {
const removedPost = await Post.remove({ _id: req.params.postId });
res.json(removedPost);
} catch (err) {
res.json({ message: err });
}
});
//Update a post
router.patch("/:postId", async (req, res) => {
try {
const updatedPost = await Post.updateOne(
{ _id: req.params.postId },
{
$set: { quote: req.body.quote }
}
);
res.json(updatedPost);
} catch (err) {
res.json({ message: err });
}
});
module.exports = router;
gitignore
/node_modules
models>Posts.js
const mongoose = require("mongoose");
const PostSchema = mongoose.Schema({
quote: {
type: String,
required: true
}
});
module.exports = mongoose.model("Posts", PostSchema);
I'm trying to create my first MongoDB app with Express & Angular & Azure Cosmos DB.
Here is my js files:
hero.model.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const heroSchema = new Schema({
id: {
type: Number,
required: true,
unique: true
},
name: String
}, {
collection: 'Heroes'
})
const Hero = mongoose.model('Hero', heroSchema);
module.exports = Hero;
mongo.js
const mongoose = require('mongoose');
mongoose.Promise = global.Promise;
const env = require('./env/environment');
const mongoUri =
mongodb:`${env.accountName}:${env.key}#${env.accountName}
.documents.azure.com:10255/?ssl=true`
function connect() {
mongoose.set('debug', true);
return mongoose.connect(mongoUri)
}
module.exports = {
connect,
mongoose
};
index.js
const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
const routes = require('./routes');
const root = './';
const port = process.env.PORT || '3000';
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.join(root, 'docs')));
app.use('/api', routes);
app.get('*', (req, res) => {
res.sendFile('docs/index.html', {root});
});
route.js
const express = require('express');
const router = express.Router();
const heroService = require('./hero.service');
router.get('/heroes', (req, res) => {
heroService.getHeroes(req, res);
});
router.post('/hero', (req, res) => {
heroService.postHero(req, res);
});
router.put('/hero/:id', (req, res) => {
heroService.putHero(req, res);
});
router.delete('/hero/:id', (req, res) => {
heroService.deleteHero(req, res);
});
module.exports = router;
app.listen(port, () => console.log(`API running on
localhost:${port}`));
hero.service.js
const Hero = require('./hero.model');
require('./mongo').connect();
function getHeroes(req, res) {
const docquery = Hero.find({});
docquery
.exec()
.then(heroes => {
res.status(200).json(heroes);
})
.catch(error => {
res.status(500).send(error);
return;
});
}
function postHero(req, res) {
const originalHero = {
id: req.body.id,
name: req.body.name
};
const hero = new Hero(originalHero);
hero.save(error => {
if (checkServerError(res, error)) return;
res.status(201).json(hero);
console.log('Hero created successfully!');
});
}
function checkServerError(res, error) {
if (error) {
res.status(500).send(error);
return error;
}
}
function putHero(req, res) {
const originalHero = {
id: parseInt(req.params.id, 10),
name: req.body.name
};
Hero.findOne({
id: originalHero.id
}, (error, hero) => {
if (checkServerError(res, error)) return;
if (!checkFound(res, hero)) return;
hero.name = originalHero.name;
hero.save(error => {
if (checkServerError(res, error)) return;
res.status(200).json(hero);
console.log('Hero updated successfully!');
});
});
}
function deleteHero(req, res) {
const id = parseInt(req.params.id, 10);
Hero.findOneAndRemove({
id: id
})
.then(hero => {
if (!checkFound(res, hero)) return;
res.status(200).json(hero);
console.log('Hero deleted successfully!');
})
.catch(error => {
if (checkServerError(res, error)) return;
});
}
function checkFound(res, hero) {
if (!hero) {
res.status(404).send('Hero not found.');
return;
}
return hero;
}
module.exports = {
getHeroes,
postHero,
putHero,
deleteHero
};
It only works when I POST a new hero for the first time and a second time gives me an error:
E11000 duplicate key error collection: admin.Heroes Failed _id or unique key constraint.
Please help!!
Thanks.
I know it's been a while but I've encountered the same problem. The solution is avoid using the field name id, rename it to UID or something. Once you done that you have to remove the entire collection and restart.
If you are following the Microsoft CosmosDB Angular tutorial, you can clone the repo below and test it on your local.
https://github.com/Azure-Samples/angular-cosmosdb
If you are using a newer version of mongoose you have to upgrade the connection string below.
//useMongoClient: true
useNewUrlParser: true