Data is not stored in mongoDB database - node.js - node.js

I write node.js code and try to insert data into a mongodb database by Postman (post) but the data is not saved, only _id and _v are inserted into the documents ,that are entered automatically. I think the problem is in the body-parser, it is deprecated, but I tried a few options and it remained deprecated. (I'm not sure the problem with bodyparser).The data were inserteded via Postman(post). This is the relevant node.js code:
const express = require ('express');
const mongoose = require ('mongoose');
const router = require ('./routes/api');
const bodyParser = require("body-parser");
const dotenv = require('dotenv');
dotenv.config();
const app = express();
.
.
.
app.use(bodyParser.json());//this bodyParser is deprecated
app.use('/',router);
model:
const mongoose = require ('mongoose');
const userSchema = mongoose.Schema({
name:{
type:String,
require
},
password:{
type:String,
minlength:8,
require
}
})
module.exports = mongoose.model('User', userSchema);
controller:
const User = require ('../models/User');
const newUser = async (req,res)=>{
let user1 = new User(
req.body);
console.log(`${user1} added`);
try{
await user1.save();
res.status(200).json({newUser:user1});
}
catch(error){
res.send(`cant save new user: ${error.message}`)
}
}
module.exports = { newUser }
This is what I wrote in Postman:
{
"name":"james",
"password":"12345678"
}
and this is the response:
{
"newUser": {
"_id": "60a68f815019f31cfc098572",
"__v": 0
}
}
I would be very happy to get help !!

Please make the following changes to get the desired result.
// In place of app.use(bodyParser.json()), use
app.use(express.json())
// Controller
const userSchema = require("../models/User");
const newUser = async (req, res) => {
let user1 = new userSchema({
name: req.body.name,
password: req.body.password,
});
console.log(`${user1} added`);
try {
await user1.save().then(() => res.status(201).json({ newUser: user1 }));
} catch (error) {
res.send(`cant save new user: ${error.message}`);
}
};
module.exports = { newUser };
Also, inside the user schema, please change require to required: true.
// Model
const userSchema = new mongoose.Schema({
name:{
type: String,
required: true
},
password:{
type: String,
minLength:8,
required: true
}
})

Modify your model.js file. It will check if anything is missing in req.body
const mongoose = require ('mongoose');
const userSchema = mongoose.Schema({
name:{
type:String,
required: true
},
password:{
type:String,
minlength:8,
required: true
}
})
module.exports = mongoose.model('User', userSchema);

Related

why unique : true schema validation is not working in mongoose?

here when I try to insert the data with proper validation it works. and when I post with wrong validation it also throws error as expected but when I use the email that was already present in my database and i had set the unique:true but it stores the document with same email.
What am i doing wrong
My model file:
const mongoose = require("mongoose")
const Userschema = new mongoose.Schema({
name:{
type:String,
required:true
},
email:{
type:String,
required:true,
unique:true,
},
password:{
type:String,
required:true
},
date:{
type:Date,
default:Date.now
}
})
const User = new mongoose.model("user", Userschema)
module.exports = User
main file:
const express = require("express");
const router = express.Router();
const User = require("../models/User");
const { body, validationResult } = require("express-validator");
router.post(
"/createuser",
[
body("name", "please enter valid name").isLength({ min: 5, max: 15 }),
body("password", "your password must be larger or equalt to 8 characters").isLength({ min: 8 }),
],
async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
try {
const data = await User.create(req.body);
res.json(data);
} catch (error) {
console.log(error);
res.send("some error occured")
}
}
);
The code is correct, If you add the unique after running the API to save the user in DB. It will not work. Because unique indexing runs the first time while creating collections. No worry, drop the data and run API. It should be working. If you don't want to drop the DB. The other solution is to write a migration task to create a unique index.
const { MongoClient } = require('mongodb');
const createIndex = async () => {
try {
const url = 'paste your db url';
const client = new MongoClient(url);
const dbName = 'paste your db name';
await client.connect();
const db = client.db(dbName);
await db.collection('users').createIndex(
{email: 1 },
{ unique: true },
);
process.exit(1);
} catch (err) {
console.log(err.stack);
}
};
createIndex();
Run the above code with 'node'.

Cannot overwrite `User` model once compiled. When resolved i get 'User' Undefined

I'm currently working on the backend of a shopping website,
while working on my post functions. I get this error
"OverwriteModelError: Cannot overwrite User model once compiled."
Everything works fine until when i go for the buy character where it needs a search query for both the User and Character and pushing the character into the array ownedCharacter in the User model.
when i remove the const User = require('../Model/User'); and test the function buy character in postman it says that the User is Undefined.
Here's the code for the model
const mongoose = require('mongoose');
const UserSchema = new mongoose.Schema({
username:{
type: String,
required : true
},
email:{
type: String,
required: true
},
password:{
type: String,
required: true,
min: 8
},
status:{
type:Boolean,
default:false
},
points:{
type:Number,
default: 0
},
rank:{
type:String,
default:"unranked"
},
avatar:{
type:String,
default:""
},
level:{
type:Number,
default:0
},
experience:{
type:Number,
default:0
},
registrationDate:{
type:Date,
default:Date.now()
},
gold:{
type:Number,
default:0
},
gems:{
type:Number,
default:0
},
ownedCharacter:[{
type:mongoose.Schema.Types.ObjectId,
ref:"Character",
}],
},{timestamps:true});
module.exports = mongoose.model("User", UserSchema);
Here's the code for the app.js
const express = require('express');
const app = express();
const mongoose = require('mongoose');
const dotenv = require('dotenv');
const bodyParser = require("body-parser");
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(express.static('uploads'));
//Import Routes
const authRoute = require ('./Route/Auth');
const authAdminRoute = require ('./Route/Admin_Auth');
const shopRoute = require('./Route/Shop');
dotenv.config();
//Connection to DataBase
mongoose.connect(
process.env.DB_CONNECT,
{useNewUrlParser: true, useUnifiedTopology: true},
()=>console.log('connected to database')
);
//MiddleWares
app.use(express.json());
//Route MiddleWares
app.use('/api/user', authRoute);
app.use('/api/admin', authAdminRoute);
app.use('/api/shop',shopRoute);
//Server Listener
app.listen(27017, ()=> console.log("Server Running"));
and here's the shop route
const router = require('express').Router();
const User = require('../Model/User');
const Character = require('../Model/Character');
const Skin = require('../Model/Skin');
//admin add character
router.post('/addCharacter', async (req, res) =>{
const character = new Character({
name:req.body.name,
price:req.body.price,
story:req.body.story,
ability:{
abilityName:req.body.abilityName,
cooldown:req.body.cooldown,
description:req.body.description
},
});
try {
const savedCharacter = await character.save();
res.json({savedCharacter});
console.log(character);
} catch (error) {
}
});
//add Skin
router.post('/addSkin/:characterId', async (req, res) =>{
const skin = new Skin({
name:req.body.name,
price:req.body.price,
description:req.body.description,
characterId: req.params.characterId
});
try {
const savedSkin = await skin.save();
res.json({skin});
console.log(skin);
} catch (error) {
}
});
//add Monsters
router.post('/addMonster/', async (req, res) =>{
const mosnter = new Monster({
name:req.body.name,
price:req.body.price,
description:req.body.description,
});
try {
const savedMonster = await monster.save();
res.json({monster});
console.log(monster);
} catch (error) {
}
});
//add Traps
router.post('/addTrap', async (req, res) =>{
const trap = new Trap({
name:req.body.name,
price:req.body.price,
description:req.body.description,
});
try {
const savedTrap = await trap.save();
res.json({trap});
console.log(trap);
} catch (error) {
}
});
//buy a Character
router.post('/buyCharacter/:characterId/:userId',async(req,res)=>{
try {
const user = await User.findOne({_id:req.params.userId});
console.log("user:"+user);
const boughtCharacter = await Character.findOne({_id:req.params.characterId});
user.ownedCharacter.push(boughtCharacter);
user.save();
res.json(boughtCharacter);
console.log(boughtCharacter);
} catch (error) {
console.log(error.message);
}
});
module.exports = router;
Is the casing correctly matched between your require statements and the file names? If the filename is actually /Model/user.js, it could throw this error.
The error message is telling you that somehow, you are declaring a model named User more than once. Unless you are explicitly doing so again in another file, you're best bet is that the User.js file is being loaded twice. There are a few reasons why that can happen, but the most likely cause is that you are importing the ../Model/User.js file in multiple places, but your casing is inconsistent.
When Node loads an import, it caches it using the resolved filename you pass to require()... and it does so in a case-sensitive manner. What that means is that if you have require(../Model/user) in one file and require(../Model/User) in
another, Node will load the same file twice, thus executing the file twice, thus attempting to set a model named User on the shared mongoose instance twice, and thus giving you the OverwriteModelError you are experiencing.
I'd do a find in your IDE and look at everywhere you are requiring that model.

Mongoose populate not working for nested object

Client.js
const mongoose = require("mongoose");
var Schema = mongoose.Schema;
const clientSchema = new mongoose.Schema(
{
name: { type: String, required: true, default: "" },
}, {
timestamps: true
}
);
module.exports = mongoose.model("Client", clientSchema);
User.js
const mongoose = require("mongoose");
var Schema = mongoose.Schema;
const userSchema = new mongoose.Schema({
name: { type: String, required: true, default: "" },
clients: [{
client: {
type: Schema.Types.ObjectId,
ref: "Client",
default: null
},
user_group: {
type: Number
default: null
}
}]
}, { timestamps: true });
module.exports = mongoose.model("User", userSchema);
auth.js (Where trying to populate Clients)
const express = require("express");
const router = express.Router();
const User = require("../models/User");
const Client = require("../models/Client");
router.post("/users", (req, res) => {
let params = req.body;
let total_client = [];
User.findOne({
email: params.email
})
.populate({
path: "clients.client",
model: Client
})
.exec((err, user) => {
console.log(user);
res.send(user);
});
});
module.exports = router;
Please check the above code. I have given code examples of my two models user.js and client.js. In user schema, I have referenced client inside an array object. While querying user, the client is not population. Please help me to get this thing done. Thanks in advance.
The following expects you to provide a name in the json body of your post request (your example uses email which does not exist in the user model). Also, your model is already defining the ref: Client and so you can simplify your request to just include the path clients.client.
router.post("/users", async (req, res) => {
const { name } = req.body;
const user = await User.findOne({ name: name }).populate('clients.client').exec();
res.send(user);
});
Solved this problem just adding an extra parameter in module export of client.js file
module.exports = mongoose.model("Client", clientSchema, "client");

I can't handle populate in mongoose

I think it's not populating categories couse when i try log 'category' in console i get
"ReferenceError: category is not defined". For me it is like in docs but as we see it's not. Is anyone can tell me what is wrong??
//model/Category.js
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const CatSchema = new Schema({
title: {
type: String,
required: true
},
body: {
type: String,
required: true
}
});
mongoose.model("categories", CatSchema, "categories");
model/Story.js
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const StorySchema = new Schema({
title: {
type: String,
required: true
},
body: {
type: String,
required: true
},
category: {
type: Schema.Types.ObjectId,
ref: "categories"
}
});
mongoose.model("stories", StorySchema, "stories");
routes/stories.js
const express = require('express');
const router = express.Router();
const mongoose = require('mongoose');
const Category = mongoose.model('categories');
const Story = mongoose.model('stories');
router.get('/add', (req, res) => {
Story.find()
.populate('category', 'title')
.then(stories => {
res.render('stories/add', {
stories: stories
});
});
});
Query.prototype.populate() returns a Query object on which you need to run .exec(), try this:
Story.find({})
.populate('category', 'title')
.exec()
.then(stories => {
res.render('stories/add', {
stories: stories
});
});
It was problem with that how I want to use it. Code is working

User.findByID is not a function

I am having an issue with node + express routing. I have a routing schema by default provided in the IDE webstorms. I am not sure if I configured everything well, because I am having this error.
I can do a GET /users and POST /users properly with correct results on postman.
routes/users.js
const express = require('express');
const router = express.Router();
const _ = require('lodash');
const {ObjectID} = require('mongodb');
const {mongoose} = require('../db/mongoose')
const {User} = require('../db/models/users')
const {Project} = require('../db/models/projects')
const {Dialog} = require('../db/models/dialogs')
(...)
router.get('/users/:userid', (req, res) => {
var id = req.params.userid.toString();
if (!ObjectID.isValid(id)) {
return res.status(404).send();
}
User.findByID(id).then((user) => {
if (!user) {
return res.status(404).send();
}
res.send({user});
}).catch(() => {
res.status(404).send();
});
});
models/users.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema
// todo refactor userschema with proper validators (view udemy course)
const UserSchema = new Schema({
email: {type: String, required: true},
password: {type: String, required: true},
name: {type: String},
company: {type: String},
phone: {type: String},
projects: [{type: Schema.Types.ObjectId, ref: 'Project'}]
});
const User = mongoose.model('User', UserSchema);
module.exports = {User}
Mikey is right. Mongoose model function is findById() not findByID() - http://mongoosejs.com/docs/api.html#model_Model.findById

Resources