New to sequelize. If I remove the {where: {username : uname}} it returns all of the records, but with it I get an error:
uname is being sent as paramter but the error log says username is not defined. Username is a field in the database.
// Find a single User with a username
export function findOne(req, res) {
const uname = req.params.username;
Users.findAll({where: {username : uname}})
.then(data => {
res.send(data);
})
.catch(() => {
res.status(500).send({
message: 'Error retrieving User with username=' + uname
});
});
}
Any idea what I am doing wrong?
User model:
import pkg from 'sequelize';
const { DataTypes } = pkg;
export default (sequelize) => {
const User = sequelize.define('user', {
title: {
type: DataTypes.STRING
},
firstname: {
type: DataTypes.STRING
},
lastname: {
type: DataTypes.STRING
},
username: {
type: DataTypes.STRING
},
password: {
type: DataTypes.STRING
},
email: {
type: DataTypes.STRING
}
});
return User;
};
Route:
import { findOne } from '../controllers/userlogin.controller.js';
import express from 'express';
export default app => {
const router = express.Router();
// Find by User
router.post('/', findOne);
app.use('/api/userlogin', router);
};
Related
I'm trying to get the current user loggedin using findById() of mongoose, but it always return null. I tried converting the id to mongoose.Types.ObjectId(string id), but i get the same result. How do i get the current user loggedin using findById(). Thanks in advance.
This is my controller
exports.createList = async (req, res, next) => {
const { error } = listValidation(req.body);
if (error) {
return res.status(404).send(error.details[0].message);
}
const list = new List({
title: req.body.title,
description: req.body.description,
createdDate: req.body.createdDate,
endDate: req.body.endDate,
creator: req.user._id,
});
try {
await list.save();
console.log("LIST CREATED");
console.log(req.user);
const user = await User.findById(mongoose.Types.ObjectId(req.user._id));
console.log(user);
user.lists.push(list);
await user.save();
console.log("LIST ADDED TO USER");
res
.status(201)
.json({ creator: { _id: user._id, username: user.username } });
} catch (error) {
res.status(400).send("An error occured");
}
};
This is the User model
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const userSchema = new Schema(
{
email: {
type: String,
required: true,
min: 6,
max: 255,
},
username: {
type: String,
required: true,
min: 6,
max: 255,
},
password: {
type: String,
required: true,
min: 6,
max: 1024,
},
lists: [
{
type: Schema.Types.ObjectId,
ref: "List",
},
],
},
{ timestamps: true }
);
module.exports = mongoose.model("User", userSchema);
Middleware to verified token and save user id to req.body
const jwt = require("jsonwebtoken");
module.exports = (req, res, next) => {
// Check if there is a token from req.header
const token = req.header("auth-token");
if (!token) {
return res.status(401).send("Access denied");
}
try {
const verified = jwt.verify(token, process.env.TOKEN_SECRET);
req.user = verified;
next();
} catch (error) {
res.status(400).send("Invalid token");
}
};
I'm learning the MERN stack and trying to create an authentication, but now I have a problem, whenever I'm trying to register, I have an error 'TypeError: User.create is not a function'.
I think that I have a problem with user model or export. Please help
INDEX.JS
const express = require("express");
const mongoose = require("mongoose");
const cors = require("cors");
const dotenv = require("dotenv");
const app = express();
const User = require("./models/User");
dotenv.config({ path: "./.env" });
app.use(express.json());
app.use(cors());
mongoose.connect(process.env.MBD_CONNECT, { useNewUrlParser: true }, (err) => {
if (err) return console.error(err);
console.log("Connected to MongoDB");
});
app.post("/api/registr", async (req, res) => {
console.log(req.body);
try {
const user = await User.create({
firstName: req.body.firstName,
lastName: req.body.lastName,
email: req.body.email,
password: req.body.password,
});
res.json({ status: "ok" });
} catch (err) {
console.log(err);
res.json({ status: "error", error: "Duplicate email" });
}
});
app.post("/api/login", async (req, res) => {
const user = await User.findOne({
email: req.body.email,
password: req.body.password,
});
if (user) {
return res.json({ status: "ok", user: true });
} else {
return res.json({ status: "error", user: false });
}
});
app.listen(3001, () => {
console.log("SERVER RUNS PERFECTLY!");
});
USER.JS (MODEL)
const mongoose = require("mongoose");
const User = new mongoose.Schema({
firstName: { type: String, required: true },
lastName: { type: String, required: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
});
const model = mongoose.model("UserData", User);
module.exports = User;
You're exporting the schema, not the model. create is a method of mongoose Model class, see document here.
const model = mongoose.model("UserData", User);
module.exports = User; // <------ problem here
It should be:
const model = mongoose.model("UserData", User);
module.exports = model;
Your model file please update with the following code snip
const mongoose = require("mongoose");
const User = new mongoose.Schema({
firstName: { type: String, required: true },
lastName: { type: String, required: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
}, { collection : 'UserData'});
const model = mongoose.model("UserData", User);
module.exports = User;
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 have three models: user, teacher, student. The users, teachers, students collections appear in the database. But everything is saved in the users collection. How to set up in the code below that student is saved in the students collection, not in users.
model
const mongoose = require('mongoose');
extend = require('mongoose-extend-schema');
const Schema = mongoose.Schema;
const userSchema = new Schema({
name: {
type: String,
trim: true,
required: true,
maxLength: 32
},
surname: {
type: String,
trim: true,
required: true,
maxLength: 32
},
email: {
type: String,
unique: true,
trim: true,
required: true,
lowercase: true
},
initials: String
});
const studentSchema = extend(userSchema, {
teachers: []
});
const teacherSchema = extend(userSchema, {
isActiveTutor: {
type: Boolean,
default: false
}
})
const User = mongoose.model('User', userSchema);
const Student = mongoose.model('Student', studentSchema);
const Teacher = mongoose.model('Teacher', teacherSchema);
module.exports = {
User,
Student,
Teacher
}
controllers
const User = require('../models/user');
const Student = require('../models/user');
const Teacher = require('../models/user');
const jwt = require('jsonwebtoken');
const nodemailer = require('nodemailer');
const expressJwt = require('express-jwt');
module.exports.signup = (req, res) => {
const {name, surname, email, password, initials, role} = req.body;
Student.User.findOne({email}).exec((err, student) => {
if (student) {
return res.status(400).json({
error: "Email is taken"
})
}
}
}
module.exports.accountActivationStudent = (req, res) => {
const {token} = req.body;
if(token) {
jwt.verify(token, process.env.JWT_ACCOUNT_ACTIVATION, function(err, decoded) {
if(err) {
console.log('JWT VERIFY IN ACCOUNT ACTIVATION ERROR', err);
return res.status(401).json({
error: 'Expired link. Signup again'
})
}
const {name, surname, email, password} = jwt.decode(token);
const student = new Student.User ({name, surname, email, password});
student.save((err, student) => {
if(err) {
console.log('SAVE Student IN ACCOUNT ACTIVATION ERROR', err);
return res.status(401).json({
error: 'Error saving student in database. Try signup again'
});
}
return res.json({
message: 'Signup success. Please signin'
});
});
});
} else {
return res.json({
message: 'Something went wrong. Try again'
})
}
};
new Student is your schema
try to like this
router.post('/', async (req, res) => {
const _studentSave = await new Student({ name, surname, email, password, initials, role });
const saveProcess = await _studentSave.save();
try{
res.json(saveProcess)
}catch(error){
throw error
}
})
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!