Mongoose only saves id and versionKey upon .save - javascript

I'm not really sure what happens here, I set up my Schema properly, and the .save function itself works, however it only generates an object with id and versionkey (_id and __v) as properties.
Here's my code for the model (in the file todo.model.js):
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
let Todo = new Schema({
desc: String,
progress: Number
});
module.exports = mongoose.model('Todo', Todo);
And here's the function:
let Todo = require('./todo.model');
...
...
router.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');
});
});
The routing etc. works, and a HTTP Post request with the correct json also returns "todo added successfully", but when i use get, i only get the id and versionKey of the object back.
{
"_id": "5ccd94f4a98874a847e54b00",
"__v": 0
}
What's going wrong here?

Related

Model.create() from Mongoose doesn´t save the Documents in my Collection

I have created a sigle app with a Schema and a Model to create a Collection and insert some Documents.
I have my todoModel.js file:
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const todoSchema = new Schema({
username: String,
todo: String,
isDone: Boolean,
hasAttachment: Boolean
});
const Todos = mongoose.model("Todo", todoSchema);
module.exports = Todos;
Then I have created a setUpController.js file with a sample of my Documents. Then I create a Model and I pass my sample of Documents and my Schema. I create a response to send tje result in JSON.
Everything good here, as I get the result in json when accessing to the route.
Here is the code:
Todos.create(sampleTodos, (err, results) => {
if (!err) {
console.log("setupTodos sample CREATED!")
res.send(results);
}
else {
console.log(`Could not create the setupTodos Database sample, err: ${err}`);
}
});
My problem is that this Documents don´t get saved in the collection !! When I access to the database, nothing is there.
This is my app.js file:
mongoose.connect("mongodb://localhost:27017/nodeTodo")
.then(connection => {
app.listen(port);
})
.catch(err => {
console.log(`Could not establish Connection with err: ${err}`);
});
Could anyone help me please ?
Thank you
Try creating an instance and making the respective function call of that instance. In your case, save the document after creating an instance and it works like a charm.
const newTodos = new Todos({
username: "username",
todo: "todos",
isDone: false,
hasAttachment: flase
});
const createdTodo = newTodos.save((err, todo) => {
if(err) {
throw(err);
}
else {
//do your staff
}
})
after the collection is created you can use the function inserMany to insert also a single document the function receives an array of objects and automatically saves it to the given collection
example:
Pet = new mongoose.model("pet",schemas.petSchema)
Pet.insetMany([
{
//your document
}])
it will save only one hardcoded document
I hope it was helpful

Mongoose populate returns empty array or list of ObjectIds

I am practicing my express.js skills by building a relational API and am struggling to populate keys in a schema.
I am building it so I have a list of properties, and those properties have units. The units have a propertyId key.
This is currently returning an empty array, whereas if i remove the populate({}) it returns an array of ObjectIds.
I've read a number of posts and some people solved this by using .populate({path: 'path', model: Model}); but this doesn't seem to be doing the trick. I think it might be the way I am adding a propertyId to the unit but I'm not sure. Can anyone see where I am going wrong? Any help will be massively appreciated.
Here are the schemas.
Property:
const mongoose = require('mongoose');
const { Schema } = mongoose;
const PropertySchema = new Schema({
title: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
},
units: [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'unit'
}
]
});
module.exports = Property = mongoose.model('property', PropertySchema);
Unit:
const mongoose = require('mongoose');
const { Schema } = mongoose;
const UnitSchema = new Schema({
title: {
type: String,
required: true
},
propertyId: {
type: Schema.Types.ObjectId,
ref: 'property'
}
});
module.exports = Unit = mongoose.model('unit', UnitSchema);
I am then creating the unit like this:
-- api/properties/:id/units --
router.post('/:id/units', async (req, res) => {
// Get fields from req.body
const { title } = req.body;
// Get current property
const property = await Property.findById(req.params.id);
try {
// Throw error if no property
if (!property) {
return res.status(400).json({ msg: 'Property not found' });
}
// Create new unit
const newUnit = new Unit({
title,
propertyId: req.params.id
});
// Add new unit to property's units array
property.units.unshift(newUnit);
// Save property
await property.save();
// Return successful response
return res.status(200).json(property);
} catch (error) {
console.error(error.message);
return res.status(500).send('Server error');
}
});
And trying to populate in the GET request
-- /api/properties/:id/units --
const Unit = require('../../models/Unit');
router.get('/:id/units', async (req, res) => {
const property = await Property.findOne({ _id: req.params.id }).populate({path: 'units', model: Unit});
const propertyUnits = property.units;
return res.status(200).json(propertyUnits);
});
If i remove the .populate({path: 'units', model: Unit});, I get a list of unit id's like this:
[
"5ff7256cda2f5bfc1d2b9108",
"5ff72507acf9b6fb89f0fa4e",
"5ff724e41393c7fb5a667dc8",
"5ff721f35c73daf6d0cb5eff",
"5ff721eb5c73daf6d0cb5efe",
"5ff7215332d302f5ffa67413"
]
I don't know, why you don't try it like this:
await Property.findOne({ _id: req.params.id }).populate('units')
I've been try that code above and it's working.
Note: Make sure to check your req.params.id is not null or undefined and make sure the data you find is not empty in your mongodb.
Updated: I've been try your code and it's working fine.
The issue was caused by inconsistent naming and not saving the new created unit as well as the updated property.
I double checked all my schema exports and references and noticed I was using UpperCase in some instances and LowerCase in others, and saved the newUnit as well as the updated property in the POST request and it worked.

MongoDB schema does not insert property when using with insertOne function

The initial problem was solved, thanks!
Now, whenever I insert the document it comes out like this:
{
_id: "5e3b64b6655fc51454548421",
todos: [ ],
title: "title"
}
It should look like this since in the schema the "title" property is above the "todos" property.
{
_id: "5e3b64b6655fc51454548421",
title: "title",
todos: [ ]
}
JavaScript
//project schema
const schema = mongoose.Schema({
title: String,
todos: []
});
const Project = mongoose.model('Project', schema);
//add a project
app.post('/addProject', (req, res) => {
const collection = db.collection('projects')
const proj = new Project({title: req.body.title});
collection.insertOne(proj, function(err, results) {
if (err){
console.log(err);
res.send('');
return
}
res.send(results.ops[0]) //retruns the new document
})
})
You're renaming your key in below line:
const proj = new Project({title: req.body.projTitle});
Your schema expects projTitle, try to change it to:
const proj = new Project({projTitle: req.body.projTitle});
Mongoose schema defines the structure of your document. Whenever you try to save additional field that's not defined in your schema it will be simply ignored by mongoose.
You are entering wrong key while creating new Project object. Change it to the correct key as per your schema and you'll be good to go.
//project schema
const schema = mongoose.Schema({
projTitle: String,
todos: []
});
const Project = mongoose.model('Project', schema);
//add a project
app.post('/addProject', (req, res) => {
const collection = db.collection('projects')
**const proj = new Project({projTitle: req.body.projTitle});** // changes are here
collection.insertOne(proj, function(err, results) {
if (err){
console.log(err);
res.send('');
return
}
res.send(results.ops[0]) //retruns the new document
})
})
Please try to look at the code below.
const collection = db.collection('projects')
const proj = new Project({projTitle: req.body.projTitle}); //make changes here

How to save array of objects in mongodb with mongoose?

I want to save complex data, ie array of objects to mongoose. I have tried few things but i couldn't save the data.
I defined my schema as above and i want to save array of objects that could have any level of nesting.
Schema
const mongoose = require('mongoose);
const PostSchema = new mongoose.Schema({
post: [{}]
});
let PostModel = mongoose.Model('Post', PostSchema)
The Data:
Here is the code I used to save the data
app.post('/saveData, async (req, res) => {
const response = await Post.create(req.body);
res.json({
data: response
});
});
app.listen(8008, () => {
console.log('server running);
});
The problem is that i cant retrieve the data. it returns array of objects equal to the number of saved array but with no data in it.
How can it be done?
This code works for me.
const PostModel = require('./Post'); //declare your model
app.post('/saveData', async (req, res) => {
const objModel = new PostModel();
objModel.post = req.body; //assign the data post array.
const response = await objModel.save();
res.json({
data: response
});
});
Your post schema looks weird.
You have a collection for Posts and then within a posts schema, you have a posts array.
What is the point of that?
The post collection already is an "array" for posts.
// Perhaps you are looking for something like this.
const PostSchema = new mongoose.Schema({
title: String,
content: String,
level: Number,
footer: String,
author: ObjectId,// who wrote the post
comments: [{
user: ObjectId,
comment: String
}],
... createdAt, updatedAt etc
});
Your data structure doesnt seem to match your schema either.
e.g
await Post.create({posts: req.body});

How to add save another Schema data to a model?

I am using mongoose with Mongodb v3.4.3
Below is my image model code
const mongoose = require("mongoose");
const CoordinateSchema = require("./coordinate");
const ImageSchema = new mongoose.Schema({
image_filename: {
type: String,
required: true
},
image_url: {
type: String,
required: true
},
coordinates: [CoordinateSchema],
});
Below is my CoordinateSchema code
const mongoose = require("mongoose");
const CoordinateSchema = new mongoose.Schema({
coordinates : {
type: Array,
default: [],
}
});
module.exports = CoordinateSchema;
Below is my api js code running on express,
router.post('/receiveCoordinates.json', (req, res, next) => {
Image.findOneAndUpdate({image_filename:req.body.file_name}).then((image) => {
})
});
How to finish this code so I can store coordinates data in Image model.
Thanks.
UPDATE
To update the coordinates inside of findOneAndUpdate, you simply check that the returned document isn't undefined (which would mean your image wasn't found). Modify your api.js code like so:
router.post('/receiveCoordinates.json', (req, res, next) => {
Image.findOneAndUpdate({image_filename:req.body.file_name}).then((image) => {
if (!image) return Promise.reject(); //Image not found, reject the promise
image.where({_id: parent.children.id(_id)}).update({coordinates: req.body.coordinates}) //Needs to be an array
.then((coords) => {
if (!coords) return Promise.reject();
//If you reach this point, everything went as expected
});
}).catch(() => {
console.log('Error occurred');
);
});
Here's my guess why it isn't working.
In ImageSchema, you are sub-nesting an array of CoordinateSchema. But CoordinateSchema is a document which already contains an array.
This is probably not what you're looking for. If you're using mongoose version 4.2.0 or higher, you can nest CoordinateSchema inside of ImageSchema as a single document. Re-write your ImageSchema like this:
// ...
const ImageSchema = new mongoose.Schema({
// ...
coordinates: CoordinateSchema,
});
If this didn't work or doesn't resolve your issue, please let me know so we can work together to find a solution.

Categories

Resources