Mongoose Model.findOne not a function - node.js

Having an issue with a model. Trying to do a model.findOne(), but I keep getting the error
TypeError: User.findOne is not a function
I have the model setup like so:
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const UserSchema = new Schema({
firstName: String,
lastName: String,
emailAddress: {
type: String,
required: true,
unique: true
},
userName: {
type: String,
required: true,
unique: true
},
password: {
type: String,
required: true
}
});
module.export = User = mongoose.model("User", UserSchema);
and I have it imported in the file that I want to find a user:
const { Strategy, ExtractJwt } = require("passport-jwt");
const log = require("./logger");
require('dotenv').config();
const fs = require("fs");
const secret = process.env.SECRET || 'thisneedstob3ch#ng3D';
const mongoose = require("mongoose");
const User = require("./models/user");
const opts = {
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: secret
};
module.exports = passport => {
passport.use(
new Strategy(opts, (payload, done) => {
User.findOne({id: payload.id})
.then(user => {
if (user) {
return done(null, {
id: user.id,
name: user.name,
email: user.email
});
}
return done(null, false);
})
.catch(err => log.error(err));
})
);
};
Regardless, I get the error. I've tried .findById() as well as .findOne()
Is there something I'm missing?

You made a typo in you user.js file, you forgot the s of module.exports:
module.exports = User = mongoose.model("User", UserSchema);

Related

TypeError: Cannot read properties of undefined (reading 'create')

const express = require("express");
const router = express.Router();
const bcrypt = require("bcrypt");
const { Users } = require("../../models/Users");
router.post("/", async (req, res) => {
const { username, password } = req.body;
bcrypt.hash(password, 10).then((hash) => {
Users.create({
username: username,
password: hash,
});
res.json("SUCCESS");
});
});
models/Users.js
module.exports = (sequelize, DataTypes) => {
const Users = sequelize.define("Users", {
username: {
type: DataTypes.STRING,
allowNull: false,
},
password: {
type: DataTypes.STRING,
allowNull: false,
},
});
return Users;
};
Hello i have problem with creating user in my db. The error is TypeError: Cannot read properties of undefined (reading 'create'). I dont know what is wrong. Help me please.
Your models/Users.js module exports a function, not the Users object that you need. Instead of having sequelize and DataTypes as function parameters, you should require them in the module:
const {sequelize, DataTypes} = require("sequelize");
module.exports = {
Users: sequelize.define("Users", {
...
})
};

CastError: Cast to ObjectId failed for value "register" (type string) at path "_id" for model "User"

I am completely Stuck tried everything possible but no luck to resolve this error
UnhandledPromiseRejectionWarning: CastError: Cast to ObjectId failed for value "register" at path "_id" for model "User"
i am using mongodb 4.2 and "mongoose": "^5.12.10"
Please anyone help me.
users_router.js
const { User } = require('../models/user_schema');
const express = require('express');
const router = express.Router();
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
router.get('/:id', async(req, res) => {
console.log(req.params.id);
const user = await User.findById(req.params.id).select('-passwordHash');
if (!user) {
res.status(500).json({ message: 'The user with the given ID was not found.' })
}
res.status(200).send(user);
})
router.post('/register', async(req, res) => {
let user = new User({
name: req.body.name,
email: req.body.email,
passwordHash: bcrypt.hashSync(req.body.password, 10)
})
console.log(user, "harman");
user = await user.save();
if (!user)
return res.status(400).send('the user cannot be created!')
res.send(user);
})
// This is Schema
user_schema.js
const mongoose = require('mongoose');
const userSchema = new mongoose.Schema({
name: {
type: String,
required: true,
},
email: {
type: String,
required: true,
},
passwordHash: {
type: String,
required: true,
}
});
userSchema.virtual('id').get(function() {
return this._id.toHexString();
});
userSchema.set('toJSON', {
virtuals: true,
});
exports.User = mongoose.model('User', userSchema);
exports.userSchema = userSchema;

array of object populate returns null mongoose

This returns null what could be the issue? I see proper user _id in the test table, I would expect user detail to be shown in the place user. As you can see under test array i made ref to user schema.
structure as follows in database
const mongoose = require('mongoose');
let UserSchema = new mongoose.Schema({
email: String,
password: String,
});
let testSchema = new mongoose.Schema({
test: [
{
title: String,
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'user',
},
},
],
});
run().catch((err) => console.log(err));
async function run() {
await mongoose.connect('mongodb://localhost:27017/test', {
useNewUrlParser: true,
useUnifiedTopology: true,
});
await mongoose.connection.dropDatabase();
const UserModel = mongoose.model('user', UserSchema);
const TestModel = mongoose.model('test', testSchema);
const newUser = { email: 'test#test.com', password: 'Alexa123' };
const user = new UserModel(newUser);
await user.save();
const newTest = { test: [{ title: 'foo', user: user._id }] };
const test = new TestModel(newTest);
await test.save();
const getTest = await TestModel.findOne({ title: 'test' })
.populate('test.user')
.exec();
console.log(getTest, 'returns null');
}
anyway solved by this
const getTest = await TestModel.findOne({ _id: test._id })
.populate('test.user')
.exec();

Mongoose - Multiple models for 1 schema

I am using mongoose v5.2.17.
I was wondering is it possible to have multiple models map to the 1 schema.
For example - I have the following model
const mongoose = require('mongoose');
const validator = require('validator');
const jwt = require('jsonwebtoken');
const _ = require('lodash');
const bcrypt = require('bcryptjs');
const UserSchema = new mongoose.Schema({
email: {
type: String,
required: true,
trim: true,
minlength: 1,
unique: true,
validate: {
validator: validator.isEmail,
message: '{VALUE} is not a valid email',
},
},
password: {
type: String,
required: true,
minlength: 6,
},
isTrialUser: {
type: Boolean,
default: true,
},
isAdminUser: {
type: Boolean,
default: false,
}
});
UserSchema.methods.toJSON = function () {
const user = this;
const userObject = user.toObject();
return _.pick(userObject, ['_id', 'email', 'isTrialUser']);
};
UserSchema.pre('save', function (next) {
const user = this;
if (user.isModified('password')) {
bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash(user.password, salt, (hashErr, hash) => {
user.password = hash;
next();
});
});
} else {
next();
}
});
const User = mongoose.model('User', UserSchema);
module.exports = { User, UserSchema };
Is it possible for me to create another AdminModel where admin specific methods can live?
I also want to return all data from the toJSON method from the AdminModel.
Please let me know if this is possible or if there is a better way to perform such a task
Thanks
Damien
If I am understanding you correctly you want to inherit the UserModel in an AdminModel and decorate that one with extra methods etc. For that you can use util.inherits (or the so called Mongoose discriminators) like so:
function BaseSchema() {
Schema.apply(this, arguments);
this.add({
name: String,
createdAt: Date
});
}
util.inherits(BaseSchema, Schema);
var UserSchema = new BaseSchema();
var AdminSchema = new BaseSchema({ department: String });
You can read more about it in Mongoose docs.
There is also a good article on the mongoose discriminators here

mongoose: .find() is not a function

None of the already existing posts on Stackoverflow have remedied my issue. I have the following in the router:
const express = require("express");
const mongoose = require("mongoose");
const User = require("./users/models");
const app = express();
const router = express.Router();
mongoose.Promise = global.Promise;
app.use(express.json());
router.post("/add", (req, res) => {
const username = req.body.username;
console.log(username);
User.find({ username: username })
.then(user => res.json(user.serialize()))
.then(res => console.log(res));
});
module.exports = router;
with the following Schema:
const UserSchema = mongoose.Schema({
username: {
type: String,
required: true,
unique: true,
},
password: {
type: String,
required: true,
},
firstName: { type: String, default: "" },
lastName: { type: String, default: "" },
bases: [{ type: mongoose.Schema.Types.ObjectId, ref: "UserVariables" }],
});
const UserVariables = mongoose.Schema({
bases: { type: "String", required: true },
users: [{ type: String }],
});
const UserVariable = mongoose.model("UserVariable", UserVariables);
const User = mongoose.model("User", UserSchema);
module.exports = { User, UserVariable };
When running the server, the .find() method returns an error message stating: TypeError: User.find is not a function. I tried several different versions in the router:
router.post("/add", (req, res) => {
const username = req.body.username;
User.find({ username: username }, user => {
console.log(user);
});
as well as:
User.findOne({ username: username })
.then(user => res.json(user.serialize()))
.then(res => console.log(res));
});
Neither of which works. In another App i am running the former and it works just fine. Any ideas ?
You're exporting an object:
module.exports = { User, UserVariable };
So to use User.find(...) from your require, you should call User.User.find(...).
Have you tried exchanging User with UserVariable.
UserVariable.findOne({ username: username })
.then(user => res.json(user.serialize()))
.then(res => console.log(res));
});
use
module.exports=User=mongoose.model('User',UserSchema)
instead of
module.exports = router;

Resources