OverwriteModelError: Cannot overwrite `User` model once compiled. at Mongoose.model - javascript

I am creating a mongoose model called User. Then when I import the model on the two different controllers the mongoose show me the error 'OverwriteModelError: Cannot overwrite User model once compiled. at Mongoose.model'
Please help me if there is any one who face this error before.
My User Model
User.js
import mongoose from "mongoose";
const UserSchema = new mongoose.Schema(
{
name: {
type: String,
required: true,
min: 2,
max: 100,
},
email: {
type: String,
required: true,
max: 50,
unique: true,
},
password: {
type: String,
required: true,
min: 5,
},
city: String,
state: String,
country: String,
occupation: String,
phoneNumber: String,
transactions: Array,
role: {
type: String,
enum: ["user", "admin", "superadmin"],
default: "admin",
},
},
{ timestamps: true }
);
const User = mongoose.model('User', UserSchema) ;
export default User;
`
The controllers
Client.js
`
import User from "../models/User.js";
export const getCustomers = async (req, res) => {
try {
const customers = await User.find({ role: "user" }).select("-password");
res.status(200).json(customers);
} catch (error) {
res.status(404).json({ message: error.message });
}
};
`
General.js
`
import User from '../models/user.js'
export const getUser = async (req, res) => {
try {
const { id } = req.params;
const user = await User.findById(id);
res.status(200).json(user);
} catch (error) {
res.status(404).json({ message: error.message });
}
}
`

Try to check if the model is already declared before exporting it:
const User = mongoose.models.User || mongoose.model('User', UserSchema);
export default User;

Related

How to Export Functions from Mongoose Model and Use it in a Controller in NodeJs

I want to create certain functions in my mongoose models and export them and then use them in my controllers.
But when i try to export and use that function in my controller it just tells me that it is not a function.
For instance i am trying to create a register function in my User model and use it in my controller, but it is throwing an error
"TypeError: User.register is not a function
"
What am i doing wrong?
Here is my code:
User.js:
const usersSchema = new Schema({
name: { type: String, required: true },
username: { type: String, required: true, unique: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true, unique: true },
verified: { type: Boolean, default: false },
})
exports.register = async (studentID, name, username, email, password, verified ) => {
const exists = await this.find({ email })
if(exists) {
throw Error("User Already Exists")
}
const salt = await bcrypt.genSalt(10)
const hash = await bcrypt.hash(password, salt)
let userDocument = {
name: name,
username: username,
email: email,
password: hash,
verified: verified
}
const user = await this.insertOne(userDocument)
return user
}
UsersController.js:
const User = require('../models/User')
router.post('/register', (req, res, next) => {
const { studentID, name, username, email, password, verified } = req.body
User.register(req.body).then((response) => {
if(response) {
res.json({
msg:"registered"
})
} else {
res.json({
msg:"failed"
})
}
})
});
use -> "module.exports = mongoose.model('User', userSchema)" at end of you model's file in order to use your "users" in other controller functions.
Below I've tweaked your code a little bit.
user.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const usersSchema = new Schema({
name: { type: String, required: true },
username: { type: String, required: true, unique: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true, unique: true },
verified: { type: Boolean, default: false },
});
module.exports = mongoose.model('User', userSchema);
usersController.js:
const bcrypt = require('bcryptjs');
const User = require('../models/user');
router.post('/register', async (req, res, next) => {
const { studentID, name, username, email, password, verified } = req.body;
try {
const exists = await User.findOne({ email: email });
if (exists) {
throw Error("User Already Exists");
}
const salt = await bcrypt.genSalt(10);
const hash = await bcrypt.hash(password, salt);
let userDocument = {
name: name,
username: username,
email: email,
password: hash,
verified: verified
}
const user = new User(userDocument); // instead of insertOne, create an new object of that model and use .save() method to save the data in collection.
const result = await user.save();
res.status(201).json({
msg: "registered"
});
} catch (err) {
const error = new Error(err);
error.httpStatusCode = 500;
return next(error);
}
});

password: ValidatorError: Path `password` is required. Node JS, express

I'm trying to make authorization with refresh tokens and access tokens via Express.
So I've met an issue that path password value after postman call is undefined,
in spite of it logs in console good.
user controller:
class UserController {
async registration(req, res, next) {
try {
const { email, password } = req.body;
console.log("pass from user controller " + password);
const userData = await userService.registration(email, password);
res.cookie("refreshtoken", userData.refreshToken, {
maxAge: 30 * 24 * 60 * 60 * 1000,
httpOnly: true,
});
return res.json(userData);
} catch (error) {
console.log(error);
}
}
}
user model:
import mongoose from "mongoose";
const UserSchema = new mongoose.Schema({
email: {
type: String,
unique: true,
required: true,
},
password: {
type: String,
required: true,
},
isActivated: { type: Boolean, default: false },
activationLink: { type: String },
});
export default mongoose.model("User", UserSchema);
user service:
import UserModel from "../models/user-model.js";
import bcrypt from "bcrypt";
import { v4 as uuid } from "uuid";
import mailService from "./mail-service.js";
import tokenService from "./token-service.js";
import UserDto from "../dtos/user-dto.js";
class UserService {
async registration(email, password) {
const candidate = await UserModel.findOne({ email });
console.log("pass form user Service " + password);
if (candidate) {
throw new Error(`Usser with this email ${email} already exists`);
}
const hashPassword = await bcrypt.hash(password, 3);
const activationLink = uuid();
const user = await UserModel.create({
email,
hashPassword,
activationLink,
});
await mailService.sendActicvationMail(email, activationLink);
const userDto = new UserDto(user);
const tokens = tokenService.generateToken({ ...userDto });
await tokenService.saveToken(userDto.id, tokens.refreshToken);
return {
...tokens,
user: userDto,
};
}
}
export default new UserService();
I'm doing it with guide, so maybe I've made some silly mistake that I ain't see.
Full error:
errors: {
password: ValidatorError: Path password is required.
at validate (/home/galich/Desktop/backend/jwt-authorization/server/node_modules/mongoose/lib/schematype.js:1337:13)
at SchemaString.SchemaType.doValidate (/home/galich/Desktop/backend/jwt-authorization/server/node_modules/mongoose/lib/schematype.js:1321:7)
at /home/galich/Desktop/backend/jwt-authorization/server/node_modules/mongoose/lib/document.js:2831:18
at processTicksAndRejections (node:internal/process/task_queues:78:11) {
properties: [Object],
kind: 'required',
path: 'password',
value: undefined,
reason: undefined,
[Symbol(mongoose:validatorError)]: true
}
},
_message: 'User validation failed'
}
You need to modify this snippet
const user = await UserModel.create({
email,
hashPassword,
activationLink,
});
to
const user = await UserModel.create({
email,
password: hashPassword,
activationLink,
});

mongoDB collection creation

i have a problem with adding a collection into my database in mongodb atlas.
I have managed to import this collection before but i accidentally deleted it and now i can't upload it again. there is no error in my terminal. There for i don't know what is wrong with my code.. (image of my code and terminal are attached below)
There is anyone who might know why is this can happen?
EDIT
I tried to open a new database and my all the collections was imported to it and once again, only the product collection doesn't
//////////////////////////////////
/* require('dotenv').config({ path: '/.env' }) */
const path = require('path')
require('dotenv').config({ path: path.resolve(__dirname, '..', '.env') })
console.dir(process.env.MONGO_URI)
const mongoose = require('mongoose')
const connectDB = async () => {
try {
mongoose.connect(process.env.MONGO_URI, {
useCreateIndex: true,
useNewUrlParser: true,
useUnifiedTopology: true,
})
console.log('MongoDB connection SUCCESS')
} catch (error) {
console.error('MongoDB connection FAIL')
process.exit(1)
}
}
console.dir(process.env.MONGO_URI)
module.exports = connectDB
////////////////////////////////////////////////////////////////
require('dotenv').config()
const productsData = require('./data/products')
const connectDB = require('./config/db')
const Product = require('./models/product')
connectDB()
const importData = async () => {
try {
/* Product.deleteMany({}) */
Product.insertMany(productsData)
console.dir('Data Imported Successfuly')
process.exit()
} catch (error) {
console.log(error)
console.error('Error Ocured In Imported Data Process', error)
process.exit(1)
}
}
importData()
my model schema
const mongoose = require('mongoose')
const products = require('../data/products')
const productSchema = new mongoose.Schema({
name: {
type: String,
required: true,
},
description: {
type: String,
required: true,
},
price: {
type: Number,
required: true,
},
countInStock: {
type: Number,
required: true,
},
imageUrl: {
type: String,
required: true,
},
})
module.exports = mongoose.model('Products', productSchema)
my code and terminal image
Product.insertMany(productsData) returns a promise, but you aren't waiting for that promise to finish before exiting the process. Add an await before it and you should be okay.
Try this to create your schema instead
const { Schema } = mongoose;
const productSchema = new Schema({
name: {
type: String,
required: true,
},
description: {
type: String,
required: true,
},
price: {
type: Number,
required: true,
},
countInStock: {
type: Number,
required: true,
},
imageUrl: {
type: String,
required: true,
},
})
const Product = mongoose.model("Product", productSchema);
Product.createCollection();

Mongoose save function is not working and returns empty {} object

I'm working on creating Auth API using Mongo and Nodejs. I have done the initial part. But when i hit the register API, it returns an empty object. Here's my scheme:
const mongoose = require('mongoose');
const userSchema = new mongoose.Schema({
name: {
type: String,
required: true,
min: 6,
max: 255
},
email: {
type: String,
required: true,
max: 255,
min: 6
},
password: {
type: String,
required: true,
max: 1024,
min: 6
},
date: {
type: Date,
default: Date.now
}
});
const User = mongoose.model('User', userSchema);
module.exports = User;
And here's where the request is being sent:
const router = require('express').Router();
const User = require('../model/User');
router.post('/register', async (req, res) => {
const user = new User({
name: req.body.name,
email: req.body.email,
password: req.body.password
});
try{
const savedUser = await user.save();
res.send(savedUser);
}catch(err){
res.status(400).send(err);
}
})
module.exports = router;
Now the user.save is not working for some reason. Not sure what i'm doing wrong. Thanks in advance.
It automatically gets the _id when it creates an object from the User Scheme.So it would be pointless to reassign
try{
await user.save();
res.send(user);
}catch(err){
res.status(400).send(err);
}

Schema hasn't been registered for model "Product"

I'm trying to create a model "Product", but when I access that by the name "Product" in the Controller, it returns me this error.
Model Product
const mongoose = require('mongoose');
const ProductSchema = new mongoose.Schema({
title: {
type: String,
required: true
},
description: {
type: String,
required: true
},
url: {
type: String,
required: true
},
createdAt: {
type: Date,
default: Date.now()
}
});
mongoose.model('Product', ProductSchema);
Product Controller
const mongoose = require('mongoose');
const Product = mongoose.model('Product');
module.exports = {
async index(req, res) {
const products = await Product.find();
return res.json(products);
}
}
Export the model from 'Model Product' and require it inside your 'Product controller'. Like this:
Model Product:
const mongoose = require('mongoose');
const ProductSchema = new mongoose.Schema({
title: {
type: String,
required: true
},
description: {
type: String,
required: true
},
url: {
type: String,
required: true
},
createdAt: {
type: Date,
default: Date.now()
}
});
module.exports=mongoose.model('Product', ProductSchema);
Product Controller
const mongoose = require('mongoose');
const Product = require('path to model product.ex-../schemas/modelProduct')
module.exports = {
async index(req, res) {
const products = await Product.find();
return res.json(products);
}
}

Categories