Trying to post data to MongoDB, get status code 200 but fail to post data - mongodb

I am a newbie to programming.
Now, I am working on a MERN stack project, trying to post data to my mongoDB database, but failed after many attempts.
Database:
There are 2 collections, 'items' and 'users' in the same database. The schemas are as follows:
Item Schema:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// Create Schema
const ItemSchema = new Schema(
{
entryDate: {
type: Date,
required: true
},
leaveDate: {
type: Date,
required: true
}
},
{
collection: 'items'
}
);
module.exports = Item = mongoose.model('Item', ItemSchema);
User Schema:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// Create Schema
const UserSchema = new Schema({
userName: {
type: String,
required: true
},
Password: {
type: String,
required: true
}
});
module.exports = User = mongoose.model('users', UserSchema);
Front-end:
handleClick = (e) => {
const API_URL = 'http://localhost:5000/api/users/';
this.setState({
startDate: this.handleStartDate(e.target.value),
endDate: this.handleEndDate(e.target.value)
});
const newDate = {
startDate: this.state.startDate,
endDate: this.state.endDate
}
const data = JSON.stringify(newDate);
axios({
method: 'post',
url: API_URL + 'addnew',
data: data,
headers: {
'Content-Type': 'application/json; charset=utf-8',
'Access-Control-Allow-Origin': '*',
"Accept": "application/json"
}
})
.then(response => {
if (response.status === 200) {
console.log('The status code is : ' + response.status);
}
})
.catch(err => {
console.log('-------Failed to add new data. Error occurred.-------');
});
};
Backend:
// #route POST api/items
// #desc Create An Item
// #access Public
router.post('/addnew', function(req, res) {
const newItem = new Item({
entryDate: req.body.entryDate,
leaveDate: req.body.leaveDate
});
console.log(newItem);
// save model to database
newItem.save(function(err) {
if (err) {
res.json({
success: false,
message: 'failed to post data'
})
} else {
res.json({
success: true,
message: 'success to post data'
})
}
})
});
I have tested the backend API with Postman, the status code is 200, but returns the error message, shown below as in the screenshot:
Screenshot of Postman
I am not sure where I went wrong, my guess is that data of the schema 'Item' could not be saved into the collection 'items', but I have no clue what I should do.
I will be really appreciated for every little help. Thanks in advance!

Try to change like this
const Item = require('path/to/ItemSchemas');
// #route POST api/items
// #desc Create An Item
// #access Public
router.post('/addnew', function(req, res) {
const newItem = new Item({
entryDate: req.body.entryDate,
leaveDate: req.body.leaveDate
});
console.log(newItem);
// save model to database. Since newItem hasn't been added to the db, we used Item.save instead
Item.save(newItem, function(err) {
if (err) {
// save to db failed!
res.status(500).json({
success: false,
message: err
})
} else {
res.json({
success: true,
message: 'success to post data'
})
}
})
});

Related

Mongoose model not persisting object

In a nutshell, I'm working on a math assessment app that takes your answers and stores them in a database and I'm having trouble adding more than one object to the backend. The Mongoose model is as such:
const mongoose = require('mongoose');
const Algebra1Schema = new mongoose.Schema({
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'user'
},
answers: {
type: Object
},
date: {
type: Date,
default: Date.now
}
})
module.exports = algebra1 = mongoose.model('algebra1', Algebra1Schema)
Here is the route:
// Submit application/json parser
var jsonParser = bodyParser.json();
router.post('/', [jsonParser, auth], async (req, res) => {
try {
let newTest = new algebra1({
answers: req.body,
user: req.user.id
})
await newTest.save();
res.json(req.body);
} catch (err) {
console.error(err.message);
res.status(500).send('Server error');
}
})
module.exports = router;
Here is the update action that makes an axios POST request:
export const submit = (results, history) => async dispatch => {
try {
const config = {
headers: {
'Content-Type': 'application/json'
}
}
const res = await axios.post('/api/algebra1', results, config);
// dispatch({
// type: QuestionActionTypes.RESET
// })
dispatch(setAlert('You\;ve finished your assessment!', 'success'));
history.push('/results');
} catch (err) {
console.error(err.message);
// dispatch({
// type: PROFILE_ERROR,
// payload: { msg: err.response.statusText, status: err.response.status }
// })
}
}
I want to add a percentage item to the algebra1 model, that looks like this:
const Algebra1Schema = new mongoose.Schema({
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'user'
},
answers: {
type: Object
},
**percent:{
type: Number**
date: {
type: Date,
default: Date.now
}
})
When I changed the route to have a percent Number added, the request goes to the database, but the answers object and percent Number aren't included. I tried updating the route to:
let newTest = new algebra1({
answers: req.body.answers,
percent: req.body.percent
user: req.user.id
})
I tried adding the following before the axios POST request:
const body = JSON.stringify({ results, percent });
and using body in place of results in the axios POST request, but the same result; nothing was persisted to the database except the user.
Any ideas as to what I'm doing wrong? I thought maybe the results object I'm sending in my action isn't correct, but when I only send the answers as req.body, it goes through and the database has the answers object.

Model.populate() is not return document in Mongoose

I have two schema,
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
// Create the User Schema
const UserSchema = new Schema({
email: {
type: String
},
password: {
type: String
}
});
module.exports = User = mongoose.model("users", UserSchema);
OR
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
// Create the Status Schema
const StatusSchema = new Schema({
admin_id:{
type: Schema.Types.ObjectId,
ref: 'users'
},
text:{
type: String
},
});
module.exports = Status = mongoose.model("Status", StatusSchema, "Status");
then i use the populate in my api route:
router.get(
"/",
passport.authenticate("jwt", {
session: false,
}),
(req, res) => {
try {
Status.find({}).populate('admin_id').exec(err, data=>{
console.log(data); // return a blank array : []
return res.sendStatus(200)
})
}
} catch (error) {
res.sendStatus(500);
}
}
);
When i call this route i got an empty array [] .... Any idea what i do wrong? I should mention that i have inserted records in status collection for both admin_id
Is there any onther way to do this ?
There is a lot of ways to do this.
You sould use this,
Status.find({}).then((doc) => {
if (doc) {
Status.populate(doc, { path: "admin_id", model: "users" }, function (
err,
data
) {
if (err) throw err;
console.log(data); //here is your documents with admin user
});
}
});

MongoDB & Mongoose: unable to populate a user's posts with .populate()

I've searched this site for days looking through the many different but similar questions on this topic to no avail.
Here's what I'd like to happen. A user signs in and their posts are automatically linked to the users collection. Eventually I'd like to link posts to the profile it was posted to, but i"m not quite there yet. Here's what I've tried so far.
In the User Schema:
const UserSchema = new Schema({
posts: [{
type: Schema.Types.ObjectId,
ref: 'posts'
}],
firstName: {
type: String,
required: true
},
lastName: {
type: String,
required: true
},
...
});
module.exports = User = mongoose.model('users', UserSchema);
In the Post Schema:
const PostSchema = new Schema({
user: {
type: Schema.Types.ObjectId,
ref: 'users'
},
text: {
type: String,
required: true
},
name: {
type: String
},
...
});
module.exports = Post = mongoose.model('posts', PostSchema);
In my users api, here's how I'm signing the user in and attempting to populate the user's posts:
const User = require('../../models/User');
router.post('/login', (req, res) => {
const { errors, isValid } = validateLoginInput(req.body);
// Check Validation
if (! isValid) {
return res.status(400).json(errors);
}
const email = req.body.email;
const password = req.body.password;
// Find user by email
User.findOne({ email })
.populate('posts')
.then(user => {
if (! user) {
errors.email = 'User not found';
return res.status(400).json(errors);
}
// Check password
bcrypt.compare(password, user.password).then(isMatch => {
if (isMatch) {
// User Matched
// Create JWT Payload
const payload = {
id: user.id,
firstName: user.firstName,
lastName: user.lastName,
name: user.firstName + ' ' + user.lastName,
avatar: user.avatar,
posts: user.posts
};
jwt.sign(
payload,
keys.secretOrKey,
{ expiresIn: 3600 }, (err, token) => {
res.json({
success: true,
token: 'Bearer ' + token,
payload
});
});
} else {
errors.password = 'Password is incorrect';
return res.status(400).json(errors);
}
});
});
});
In the posts api, here's how the post is being submitted:
router.post('/', passport.authenticate('jwt', { session: false }), (req, res) => {
const { errors, isValid } = validatePostInput(req.body);
if (! isValid) {
// Return errors with 400 status
return res.status(400).json(errors)
}
const newPost = new Post({
text: req.body.text,
name: req.body.name,
avatar: req.body.avatar,
user: req.user.id
});
newPost.save().then(post => res.json(post));
});
Currently, all I'm seeing is an empty array and no errors. I've been spinning my wheels on this one for a couple days now so any help would be appreciated. Thanks!
I think you forgot to save the _id of your new post to the User model so that the populate() can lookup the posts to populate:
newPost.save().then(post => {
User.update({ _id: req.user.id }, { $push: { posts: post._id }}, (err) => {
res.json(post));
});
});

MongoDb NodeJs RangeError: Maximum call stack size exceeded when pushing message

I'm learning how to create a MEAN app and I'm having a problem when I try to push a message into a messages array in my User Model.
I can create a new message and pass the user object but when trying to pass the message object into the user.messages array I get an error in the console 'RangeError: Maximum call stack size exceeded'.
I'll post my User and Message Models and the Message Route code.
Message Model
let mongoose = require('mongoose');
let Schema = mongoose.Schema;
let User = require('./user');
let schema = new Schema({
content: {
type: String,
required: true
},
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
}
});
module.exports = mongoose.model('Message', schema);
User Model
let mongoose = require('mongoose');
let Schema = mongoose.Schema;
let mongooseUniqueValidator = require('mongoose-unique-validator');
let schema = new Schema({
firstName: {
type: String,
required: true
},
lastName: {
type: String,
required: true
},
password: {
type: String,
required: true
},
email: {
type: String,
required: true,
unique: true
},
messages: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Message'
}]
});
schema.plugin(mongooseUniqueValidator);
module.exports = mongoose.model('User', schema);
And my Route code
let express = require('express');
let router = express.Router();
let jwt = require('jsonwebtoken');
let User = require('../models/user');
let Message = require('../models/message');
router.get('/', function (req, res, next) {
Message.find()
.exec(function (err, messages) {
if (err) {
return res.status(500).json({
title: 'An error occurred',
error: err
});
}
res.status(200).json({
message: 'Success',
obj: messages
});
});
});
// Protect Routes
router.use('/', (req, res, next) => {
jwt.verify(req.query.token, 'secret', (err, decoded) => {
if (err) {
return res.status(401).json({
title: 'Not Authenticated',
error: err
});
}
next();
});
});
router.post('/', (req, res, next) => {
let decoded = jwt.decode(req.query.token);
User.findById(decoded.user._id, (err, user) => {
if (err) {
return res.status(500).json({
title: 'An error occurred',
error: err
});
}
let message = new Message({
content: req.body.content,
user: user
});
message.save((err, result) => {
if (err) {
return res.status(500).json({
title: 'An error occurred',
error: err
});
}
user.messages.push(result);
user.save();
res.status(201).json({
message: 'Saved message',
obj: result
});
});
});
});
module.exports = router;
I believe the problem comes form the post route
user.messages.push(result);
Thanks
You are using refs in your schemas so you should store the _id value rather than the whole object:
...
let message = new Message({
content: req.body.content,
user: user._id
})
...
...and:
user.messages.push(result._id)
I hope this helps solve your problem.

Mongoose - how to move object to another collection

My db include following collections:
users
deleted_users
My code is following:
const name = { type: String, required: true, index: { unique: true } };
const UserSchema = new mongoose.Schema({ name });
const DeletedUserSchema = new mongoose.Schema({ name }, {
versionKey: 'version',
});
const UserModel = mongoose.model('User', UserSchema);
const DeletedUserModel = mongoose.model('Deleted_user', DeletedUserSchema);
router.put('/:id/move', (req, res) => {
UserModel.findOne(
{ _id: id }
).then((user) => {
if (!user) {
return fail(...);
}
console.log(`moving user width id ${id}`);
const newUser = new DeletedUserModel(user);
return newUser.save()
.then(
() => {
console.log('ok');
})
.catch((err) => {
console.log('catch err ', err);
});
});
}
but I always receive
{ Error
at model.wrappedPointCut [as save] (/~/prj/node_modules/mongoose/lib/services/model/applyHooks.js:111:29)
at UserModel.findOne.then (/~/prj/src/routes/user/index.js:123:20)
at process._tickDomainCallback (internal/process/next_tick.js:135:7)
message: 'No matching document found for id "58dd804c434bdc1848d491cd"',
name: 'VersionError' }
Can you check that this id you are querying is not a String but an ObjectId because I think you are passing a String as id.