'MongoDB - Error: document must have an _id before saving
I've been struggling so much with this project. I am following a tutorial that is out of date in some areas, for instance their version of Jquery used a totally different format for some functions and I had to do a lot of changing around. But I think I am down to one last major problem that I can't seem to find a fix for. In my Schema variable I've got the _id, username, and password types
var UserSchema = new mongoose.Schema({
_id: mongoose.Schema.ObjectId,
username: String,
password: String
});
but when I go to try to add a new user to my app, instead of getting the alert I am supposed to get, it pops up as [object Object] and nothing gets added to the database. Then this error pops up in the mongo cmd
"Error: document must have an _id before saving".
I've tried commenting out the _id line and I get the right message but still nothing shows up in my database.
Solution 1:[1]
Its pretty simple:
- If you have declared _id field explicitly in schema, you must initialize it explicitly
- If you have not declared it in schema, MongoDB will declare and initialize it.
What you can't do, is to have it in the schema but not initialize it. It will throw the error you are talking about
Solution 2:[2]
You can write your model without _id so it will be autogenerated
or
you can use .init() to initialize the document in your DB.
Like:
const mongoose = require('mongoose');
const UserSchema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
username: String,
password: String
})
module.exports = mongoose.model('User', UserSchema);
and then
const User = require('../models/user');
router.post('/addUser',function(req,res,next){
User.init() // <- document gets generated
const user = new User({
username: req.body.username,
password: req.body.password
})
user.save().then((data)=>{
console.log('save data: ',data)
// what you want to do after saving like res.render
})
}
Solution 3:[3]
Try below snippet I wanted to name _id as userId you can do without it as well.
var Schema = mongoose.Schema,
ObjectId = Schema.ObjectId;
var UserSchema = new Schema({
username: String,
password: String
});
UserSchema.virtual('userId').get(function(){
return this._id;
});
Solution 4:[4]
If you are using mongoose with nest js
and GraphQL
, I have fixed it by changing the id
to _id
and removing the @prop
above it even the null value of the id
problem has vanished. example on github
import { ObjectType, Field, Int, ID } from '@nestjs/graphql';
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { Document } from 'mongoose';
import { User } from 'src/user/entities/user.entity';
import * as mongoose from 'mongoose';
export type SchoolDocument = School & Document;
@ObjectType()
@Schema()
export class School {
@Prop()//remove this
@Field(() => ID,{ nullable: true })
_id: string;
@Prop()
@Field(() => String,{ nullable: true })
name: string;
@Field(()=>[User],{nullable:true})
users:User[];
}
export const SchoolSchema= SchemaFactory.createForClass(School);
Solution 5:[5]
_id is added automatically by MongoDb.
If you want to keep _id on your data structure be sure to initialize correctly:
import { Types } from "mongoose";
const obj = new UserSchema({
"_id": new Types.ObjectId(),
"username": "Bill",
"password" : "...."
});
Solution 6:[6]
NestJS with mongoose (@nestjs/mongoose) solution
I fixed the error by
- Removing
@Prop()
above_id
- Add
mongoose.Types.ObjectId
as type to_id
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import mongoose from 'mongoose';
import { Document } from 'mongoose';
export type CompanyDocument = Company & Document;
@Schema()
export class Company {
_id: mongoose.Types.ObjectId;
@Prop({ unique: true })
name: string;
}
export const CompanySchema = SchemaFactory.createForClass(Company);
Solution 7:[7]
In my case, I accidentally had the following at the end of my Schema. Removing that worked:
{ _id: false }
Solution 8:[8]
Look the way i fixed was i put just id in json post request and not _id.
Solution 9:[9]
No need to specify the document _id in your model. The system generates the id automatically if you leave out the _id like so:
var UserSchema = new mongoose.Schema({
username: String,
password: String
});
That being said, if you still want to generate the _id yourself, see the answers above.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | rootfuchs |
Solution 3 | user3172272 |
Solution 4 | |
Solution 5 | Nirgn |
Solution 6 | Nivethan |
Solution 7 | Sandip Subedi |
Solution 8 | majidshakeelshawl |
Solution 9 | karlzafiris |