I'm new at elastic and I'm facing error...I try to follow documentation and some tutorial that I found but on first step I get error that I'm not able to fix :(
This is my code
const mongoose = require('mongoose')
const mongoosastic = require('mongoosastic')
const userSchema = new mongoose.Schema({
name: { type: String, es_indexed: true },
email: { type: String },
city: { type: String }
})
userSchema.plugin(mongoosastic, {
"host": "localhost",
"port": 9200
})
const User = mongoose.model('elastic', userSchema);
User.createMapping(function (err, mapping) {
if (err) {
console.log("error creating mapping");
console.log(err);
} else {
console.log("Mapping successfully created");
console.log(mapping);
}
});
module.exports = User;
And this is photo of the error
Related
I want to use mongoose discriminator for my project to create a collection of users in which there is a document of owner which I want to implement using discriminators. But I am getting an error of
throw new Error('The 2nd parameter to mongoose.model() should be a ' +
^
Error: The 2nd parameter to mongoose.model() should be a schema or a POJO
at Mongoose.model (D:\Github\Food-Delivery-Website\node_modules\mongoose\lib\index.js:473:11)
at Object. (D:\Github\Food-Delivery-Website\models\Owner.js:21:27)
Code is given below:
// This file is models/User.js
const mongoose = require('mongoose');
const { Schema } = mongoose;
const options = { discriminatorKey: 'kind' };
const UserSchema = new Schema(
{
userName: {
type: String,
required: true,
unique: true,
},
restOwned: {
// type: [Schema.Types.ObjectId],
type: Number,
},
},
options,
);
module.exports = mongoose.model('User', UserSchema);
Below is the next file
// This file is models/Owner.js
const mongoose = require('mongoose');
const { Schema } = mongoose;
const User = require('./User');
const OwnerSchema = User.discriminator(
'Owner',
new Schema({
isOwner: {
type: Boolean,
required: true,
},
restName: {
type: String,
required: true,
},
}),
);
module.exports = mongoose.model('Owner', OwnerSchema);
Then I import these two files in userController.js
//This file is controllers/userController.js
const User = require('../models/User');
const Owner = require('../models/Owner');
exports.addUser = async (req, res) => {
try {
const newUser = new User({
userName: req.body.userName,
restOwned: req.body.restOwned,
});
const user = await newUser.save();
res.status(201).json({
status: 'Success',
user,
});
} catch (err) {
res.status(500).json({
status: 'failed',
message: 'Server Error: Failed Storing the Data.',
err,
});
}
};
exports.addOwner = async (req, res) => {
try {
const newOwner = new Owner({
isOwner: req.body.isOwner,
restName: req.body.restName,
});
const owner = await newOwner.save();
res.status(201).json({
status: 'Success',
owner,
});
} catch (err) {
res.status(500).json({
status: 'failed',
message: 'Server Error: Failed Storing the Data.',
err,
});
}
};
What am I doing wrong here?
enter image description here
The Model.discriminator() method returns a Model.
So you can directly export the discriminator and use it as the model
// This file is models/Owner.js
const mongoose = require('mongoose');
const { Schema } = mongoose;
const User = require('./User');
//Directly export the discriminator and use it as the model
module.exports = User.discriminator(
'Owner',
new Schema({
isOwner: {
type: Boolean,
required: true,
},
restName: {
type: String,
required: true,
},
}),
);
//module.exports = mongoose.model('Owner', OwnerSchema);
I'm working with routes on node js. I created a user model shown below -
const mongoose = require("mongoose");
const bcrypt = require("bcrypt");
const jwt = require("jsonwebtoken");
const validator = require("validator");
require("dotenv").config();
const userSchema = mongoose.Schema(
{
email: {
type: String,
required: true,
unique: true,
trim: true,
lowercase: true,
validate(value) {
if (!validator.isEmail) {
throw new Error("Invalid Email");
}
},
},
password: {
type: String,
required: true,
trim: true,
},
role: {
type: String,
enum: ["user", "admin"],
default: "user",
},
name: {
type: String,
required: true,
maxlength: 21,
},
phone: {
required: true,
type: Number,
maxlength: 12,
},
},
{ timestamps: true },
);
userSchema.pre("save", async function (next) {
if (user.isModified("password")) {
// hash the password
const salt = await bcrypt.genSalt(10);
const hash = await bcrypt.hash(this.password, salt);
this.password = hash;
}
next();
});
const User = mongoose.model("User", userSchema);
module.exports = {
User,
};
And then I created a file containing user routes shown below -
const express = require("express");
const router = express.Router();
require("dotenv").config();
const { User } = require("../../models/userModel");
router.route("/signup").post(async (req, res) => {
// const { email, password, name, phone } = req.body;
console.log(req.body);
// try {
// // Check if user email exists
// // create user instance and hash password
// const user = new User({
// email: req.body.email,
// password: req.body.password,
// name: req.body.name,
// phone: req.body.phone,
// });
// // generate jwt token
// console.log("user is saving");
// const userDoc = await user.save();
// // send email
// // save....send token with cookie
// res
// .cookie("access-token", "jflsakjusdilfjadslfj32j43lrf")
// .status(200)
// .send(userDoc);
// } catch (error) {
// res
// .status(400)
// .json({ message: "Error while creating user", error: error });
// }
const user = new User({
name: req.body.name,
email: req.body.email,
password: req.body.password,
phone: req.body.phone,
});
user
.save()
.then((doc) => {
console.log("User saved");
res.send(doc);
})
.catch((err) => {
console.log(err);
});
});
module.exports = router;
But don't know why I'm getting this error -
ReferenceError: user is not defined
at model.<anonymous> (D:\CovidHelpers\CovidHelpers\server\models\userModel.js:46:3)
at callMiddlewareFunction (D:\CovidHelpers\CovidHelpers\node_modules\kareem\index.js:483:23)
at model.next (D:\CovidHelpers\CovidHelpers\node_modules\kareem\index.js:58:7)
at _next (D:\CovidHelpers\CovidHelpers\node_modules\kareem\index.js:107:10)
at D:\CovidHelpers\CovidHelpers\node_modules\kareem\index.js:508:38
at processTicksAndRejections (internal/process/task_queues.js:75:11)
I have just created a new project in mongodb, gave database and network access and it's connecting successfully but also getting this error
I have done this before also and it was working fine but don't know why am I getting this now :(
Any help is appreciated
save is document middleware and in document middleware functions, this refers to the document. So in your case, I believe it should be this.isModified("password") instead of user.isModified("password").
You can delete userSchema.pre() middleware and transfer the password hashing logic inside the router. Also you can simplify your router code like this:
router.route("/signup").post(async (req, res) => {
try {
const salt = await bcrypt.genSalt(10);
const hash = await bcrypt.hash(req.body.password, salt);
req.body.password = hash;
let user = await User.create(req.body)
res.status(200).json(user)
} catch (error) {
res.status(400).json({ error: error });
}
});
RECOMMENDATION:
I would recommend you to try the great Mongoose plugin called passport-local-mongoose that will do this for you out of the box, and it will also give you some nice authentication features if you are using passport for authentication.
Package: https://www.npmjs.com/package/passport-local-mongoose
You don't actually get access to the document, in the mongoose's pre('save') hook.
For your usecase, you can do the hasing before you save the user.
I have 3 sequelize models that i have defined imported into a file called sequelize.js like so:
const { Sequelize } = require("sequelize");
const UserModel = require("./models/user");
const ItemModel = require("./models/item");
const ReservationModel = require("./models/reservation");
const config = require("./dbconfig");
const db = config.database;
const Item = ItemModel(sequelize, Sequelize);
const User = UserModel(sequelize, Sequelize);
const Reservation = ReservationModel(sequelize, Sequelize);
Reservation.hasMany(Item);
Item.belongsTo(Reservation);
Reservation.belongsTo(User);
I then try to export them:
module.exports = { Item, User, Reservation };
However, when I try to access one of them and use a model function, I get an error.
const Model = require("../../sequelize");
const passport = require("passport");
module.exports = (app) => {
app.post("/registerUser", (req, res, next) => {
passport.authenticate("register", (err, user, info) => {
if (err) {
console.log(err);
}
if (info !== undefined) {
console.log(info.message);
res.send(info.message);
} else {
req.logIn(user, (err) => {
const data = {
first_name: req.body.first_name,
last_name: req.body.last_name,
email: req.body.email,
username: user.email,
};
Model.User.findOne({
where: {
email: data.username,
},
}).then((user) => {
user
.update({
first_name: data.first_name,
last_name: data.last_name,
email: data.email,
})
.then(() => {
console.log("user created in db");
res.status(200).send({ message: "user created" });
});
});
});
}
})(req, res, next);
});
};
results in
TypeError: User.findOne is not a function
This is not an issue when I just export one of them.
module.exports = User;
const User = require("./sequelize");
...
User.findOne(...) //works
I've tried multiple ways of exporting, but none seem to work.
e.g
module.exports = {
Item: Item,
User: User,
Reservation: Reservation,
}
and
exports.Item = Item;
exports.User = User;
exports.Reservation = Reservation;
edit: Here is my user model for reference
module.exports = (sequelize, type) => {
return sequelize.define(
"user",
{
id: {
type: type.INTEGER,
primaryKey: true,
autoIncrement: true,
},
first_name: type.STRING,
last_name: type.STRING,
credentials: type.STRING,
email: {
type: type.STRING,
allowNull: false,
},
password: {
type: type.STRING,
allowNull: false,
},
},
{
tableName: "Users",
}
);
};
Why cant I export these multiple objects?
I have the exact structure you're using by importing all sequelize models into one file then module.exporting them in an object and the only thing I see thats different is how you define your models. I might be out of date but I learned as such:
const Sequelize = require('sequelize');
const db = require('../db');
module.exports = db.define('users', {
id: {
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER,
unique: true
},
}, {
timestamps: true,
});
Db declaration
const Sequelize = require('sequelize');
const db = new Sequelize(
process.env.DATABASE_URL, {
logging: false
}
);
module.exports = db;
Then your central import
const User = require('./user');
const Order = require('./order');
Order.belongsTo(User)
User.hasMany(Order)
module.exports = {
User,
Order
};
Then using it
const models = require('./models');
const results = await models.User.destroy({
where: {
id: id
}
});
if(results){
return results;
}
Found what was wrong. In my passport.js file, where I defined my localStrategy, I was doing an incorrect import.
My export in sequelize.js was
modules.export = {Item, User, Reservation};
while my import in passport.js was just
const User = require("../sequelize");
when it should have been
const Model = require("../sequelize");
const User = Model.User;
looks like I had it imported correctly in my signUp route, but not in my passport config file!
I'm new to MongoDB/Mongoose and trying to figure out how to map relationships between Schema. I don't think issue is with .populate(). At creation of new user and clients, I do not see the relationship reflected in collection
User (login via local/social) has many Clients.
A set of Clients belong to 1 User
Is this the correct way to declare foreign key? {type: Schema.Types.ObjectId, ref: 'Client'}
Should both Schema have the each other's foreign key to relate to one another?
Is there any additional code required when creating User/Client in order for the data from foreign key to show up? I read something about populate()
User
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var userSchema = new Schema({
local: {
id: String,
email: String,
password: String,
name: String,
mobile: String,
clients: {type: Schema.Types.ObjectId, ref: 'Client'}
},
google: {
id: String,
token: String,
email: String,
name: String,
clients: {type: Schema.Types.ObjectId, ref: 'Client'}
}
});
module.exports = mongoose.model('User', userSchema);
Client
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var clientSchema = new Schema({
id: String,
firstname: String,
lastname: String,
mobile: String,
user: {type: Schema.Types.ObjectId, ref: 'User'}
});
module.exports = mongoose.model('Client', clientSchema);
Create User
app.post("/api/user", function (req, res) {
const user = req.body;
console.log(user);
User.findOne({ 'local.email': user.email },
function (err, result) {
if (err) {
console.log(err);
handleError(err, res);
return;
}
if (result) {
res.status(500).send("Email already exists in database");
} else {
var newUser = new User();
newUser.local.password = generateHash(user.password);
newUser.local.email = user.email;
newUser.local.name = user.name;
newUser.local.mobile = user.mobile;
newUser.save(function (err, result) {
res.status(201).send("User added to database");
});
}
});
});
Create Client
app.post("/api/client", function (req, res) {
const client = req.body;
console.log(client);
Client.findOne({
$and: [
{ firstname: client.firstname },
{ lastname: client.lastname }
]
},
function (err, result) {
if (err) {
console.log(err);
handleError(err, res);
return;
}
if (result) {
res.status(500).send({msg:"Client already exists in database"});
} else {
var newClient = new Client();
newClient.firstname = client.firstname;
newClient.lastname = client.lastname;
newClient.mobile = client.mobile;
newClient.save(function (err, result) {
res.status(201).send("Client added to database");
});
}
});
});
I'm trying to understand how MongoDB works.
I created a local MongoDB with the following collection:
db.user.find().pretty()
{
"_id" : ObjectId("5a05844833a9b3552ce5cfec"),
"firstname" : "Emanuel",
"lastname" : "Mars",
"username" : "mae",
"email" : "myEmail#email.ch",
"passwort" : "mae",
"role" : 1
}
Now, I want to connect to the DB with Express.
The connection works, but I don't get any data.
This is the model I created:
var userSchema = new mongoose.Schema({
firstname: { type: String },
lastname: { type: String },
username: { type: String },
email: { type: String },
passwort: { type: String },
role: { type: Number }
}, { collection : 'user' });
module.exports = mongoose.model('user', userSchema);
And this is how I want to get all Users in the collection user:
var User = require('../../models/user');
User.find({}, function (err, user) {
console.log('yes', user);
});
Upon success, it should handle a login process with users from the MongoDB.
Solved:
I forgot to add the DB name at the end of the connect URL.
//server.js
var configDB = require('./config/database.js');
mongoose.connect(configDB.url);
const db = mongoose.connection;
db.on('error', () => {
console.log('DB connection Error');
});
db.once('open', () => {
console.log('DB is connected');
});
require('./config/passport')(passport);
//user.js
const mongoose = require('mongoose');
const bcrypt = require('bcrypt-nodejs');
var userSchema = new mongoose.Schema({
firstname: { type: String },
lastname: { type: String },
username: { type: String },
email: { type: String },
passwort: { type: String },
role: { type: Number }
}, { collection : 'user' });
userSchema.methods.generateHash = function(password) {
return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
};
userSchema.methods.validPassword = function(password) {
return bcrypt.compareSync(password, this.local.password);
};
module.exports = mongoose.model('user', userSchema);