MongoDB schema does not insert property when using with insertOne function - javascript

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

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

How to get the id of a document before even saving it in mongoose?

I have a simple controller that creates a post for a user. Another schema is linked to it. When I try to create a new post, I need to get the id of the post so that I can link other schema to it.
Here is the schema:
const mongoose = require("mongoose");
const User = require("./User");
const View = require("./View");
const ArticleSchema = new mongoose.Schema({
title: {
type: String,
required: true,
trim: true,
},
body: {
type: String,
required: true,
},
status: {
type: String,
default: "public",
enum: ["public", "private"],
},
user: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
},
views: {
type: mongoose.Schema.Types.ObjectId,
ref: "View",
},
createdAt: {
type: Date,
default: Date.now,
},
});
module.exports = mongoose.model("Article", ArticleSchema);
It is fine when I want to link the user field because I have that stored in memory.
But the view field requires postId of that particular document. And I can't get it without first creating the document.
My create post controller:
module.exports.createArticleController = async function (req, res) {
try {
req.body.user = req.User._id;
const article = await Article.create(req.body).exec()
res.redirect(`/${article.title}/${article._id}`);
} catch (e) {
console.error(e);
}
};
So my question is,
How can i get the id in the process of executing the model.create() so that i can link the view to that id. Maybe something using the this operator
I don't want to use update after create.
You can generate your own id and save it
ObjectId id = new ObjectId()
You can get object Id's right after creating an instance of Model or create your own object id's and save them.
Here's how i achieved it:
module.exports.createArticleController = async function (req, res) {
try {
const instance = new Article();
instance.title = req.body.title;
instance.body = req.body.body;
instance.status = req.body.status;
instance.user = req.User._id;
instance.views = instance._id;
const article = await instance.save();
if (article) {
res.redirect(`/${article.title}/${article._id}`);
}
} catch (e) {
console.error(e);
}
};
Or you can create them and save it to the db.
var mongoose = require('mongoose');
var myId = mongoose.Types.ObjectId();
const instance = new YourModel({_id: myId})
//use it
Continue reading
How do I get the object Id in mongoose after saving it.
Object Id's format and usage
You can just simply create a schema ovject like this:
const task: TaskDocument = new this.taskSchema({ ...createTaskDto })
This is from one of my projects, since the ObjectId from MongoDB is based on the operating machine and the time it is created, it doesn't need the database to generate the id.
You can now access task._id to get your id without saving it.

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.

Mongoose only saves id and versionKey upon .save

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?

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