I can't seem to set the User model properly. I've implemented some instance methods that don't seem to be working
var UserDetails = mysequelize.sequelize.define('user_tb', {
id: {
autoIncrement: true,
type: mysequelize.sequelize.Sequelize.INTEGER,
allowNull: false,
},
username: {
type: mysequelize.sequelize.Sequelize.STRING,
primaryKey: true,
unique: true,
},
hierarchyid: {
type: mysequelize.sequelize.Sequelize.STRING
},
password: {
type: mysequelize.sequelize.Sequelize.STRING,
validate: {
len: {
args: [6, 15],
msg: "Please enter a password with at least 6 chars but no more than 15"
}
},
allowNull: false
},
customerid: {
type: mysequelize.sequelize.Sequelize.INTEGER
},
statususer: {
type: mysequelize.sequelize.Sequelize.STRING,
allowNull: false
},
userid: {
unique: true,
type: mysequelize.sequelize.Sequelize.STRING,
allowNull: false
},
authtoken: {
unique: true,
type: mysequelize.sequelize.Sequelize.STRING,
allowNull: false
}
},
{
tableName: 'user_tb',
timestamps: false,
freezeTableName: true
});
UserDetails.prototype.toJSON = function(){
var user = this;
var userObject = user.toObject();
return _.pick(userObject,['userid','password']);
};
UserDetails.prototype.findByCredentials = function(userid, password)
{
console.log('Sunddep');
var User = this;
// return User.fin
User.findOne({userid}).then((user)=> {
if(!user)
{
return Promise.reject();
}
return new Promise((resolve,reject) => {
bcrypt.compare(password,user.password,(err,res) => {
if(res)
{
resolve(user);
}
else{
reject();
}
})
})
});
}
UserDetails.prototype.generateAuthToken = function()
{
var user = this;
var access = 'authtoken';
var token = jwt.sign({userid:
user.userid.toHexString(),access},process.env.JWT_SECRET).toString();
user.build({
access: token
});
user.save().then(() =>{
return token;
});
}
module.exports = {UserDetails}
server.js
app.post('/user/login', (req, res) => {
console.log(req.body);
var body = _.pick(req.body, ['userId', 'password']);
user.findByCredentials(body.userId, body.password).then(() => {
res.send('Sundeep');
},
(e) => {
sendData: ({
wsState: '0',
messageCode: 'WS000001',
message: 'No user find with this Id',
userData: []
});
res.status(400).send(sendData)
});
});
Hi, I am getting error while calling instance method from other class. Can any one tell me how can i achieve it
UserDetails.prototype.findByCredentials = function(userid, password) {.....}
But while run the server.js file i getting error like UserDetails.findByCredentials is not a function while calling from other class
Thanks for help in advance.
Related
I am new to sequelize SQL ORM nodejs. I am facing problem with associations.When I try to make a join query. It throws an association error. here is my code snippet.
server.js
app.get("/", (req, res) => {
db_conn.syncModels(req, res);
});
db_connection.js
require("dotenv").config();
const { Sequelize, DataTypes } = require("sequelize");
const crypto = require("crypto");
class DbConnection {
constructor() {
this.db = {};
this.sequelizeObj = new Sequelize(
process.env.DB_NAME,
process.env.DB_USER,
process.env.DB_PASS,
{
host: process.env.DB_URI,
dialect: "mysql",
logging: true,
}
);
this.userRoles = [
{
role_name: "SuperAdmin",
},
{
role_name: "Admin Assistant",
},
{
role_name: "HR Manager",
},
{
role_name: "Department Head",
},
{
role_name: "Assistant Manager",
},
{
role_name: "Employee",
},
];
this.defaultUser = {
user_name: "SuperAdmin",
user_email: "superadmin#" + process.env.BASE_URL,
user_password: crypto
.createHash("md5")
.update("SuperAdmin")
.digest("hex"),
role_id: 100000,
};
}
sequelize() {
return this.sequelizeObj;
}
connect() {
this.sequelizeObj
.authenticate()
.then(() => {
console.log("Connection has been established successfully.");
})
.catch((error) => {
if (error.message.includes("Unknown database")) {
this.createdb();
} else {
console.error("Unable to connect to the database: ", error);
}
});
}
async createdb() {
try {
const sequelize = new Sequelize(
"",
process.env.DB_USER,
process.env.DB_PASS,
{
host: process.env.DB_URI,
dialect: "mysql",
logging: true,
}
);
const createdb = await sequelize.query(
`CREATE DATABASE IF NOT EXISTS ${process.env.DB_NAME};`
);
console.log("Database Created")
} catch (err) {
console.log(err);
}
}
disconnect() {
this.sequelizeObj
.close()
.then(() => {
console.log("Connection has been closed successfully.");
})
.catch((error) => {
console.error("Unable to disconnect: ", error);
});
}
syncModels(payload, cb) {
this.db.Sequelize = Sequelize;
this.db.sequelize = this.sequelizeObj;
this.db.sequelize
.sync({ force: true })
.then((res) => {
console.log("Environment Configured");
})
.then(async () => {
await this.db.user_roles.bulkCreate(this.userRoles);
})
.then(() => {
console.log("User Roles Created");
})
.then(() => {
cb.status(200).send("Environment Configured");
})
.catch((err) => {
cb.status(400).send("Environment Configuration Error " + err);
});
// specifying models
this.db.users = require("../Auth/models/auth.model")(
this.sequelizeObj,
DataTypes
);
this.db.user_roles = require("../Auth/models/roles.model")(
this.sequelizeObj,
DataTypes
);
// Method 01
// Relation of user and user-roles
this.db.users.hasOne(this.db.user_roles, {
foreignKey: "role_id",
as: "role",
});
this.db.user_roles.belongsTo(this.db.users, {
foreignKey: "role_id",
as: "role",
});
}
random_password(length) {
var result = "";
var characters =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
var charactersLength = characters.length;
for (var i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
}
}
module.exports = DbConnection;
Users.model.js
module.exports = (sequelize, DataTypes) => {
const Users = sequelize.define(
"users",
{
user_id: {
type: DataTypes.INTEGER,
allowNull: false,
autoIncrement: true,
primaryKey: true,
unique: true,
},
user_name: {
type: DataTypes.STRING,
allowNull: false,
},
user_email: {
type: DataTypes.STRING,
allowNull: false,
unique: true,
},
user_password: {
type: DataTypes.STRING,
allowNull: false,
},
role_id: {
type: DataTypes.INTEGER,
allowNull: false,
},
},
{
initialAutoIncrement: 1900000,
}
);
// Method 02
Users.associate = (models) => {
Users.hasOne(models.UserRoles, { foreignKey: "role_id" });
};
return Users;
};
UserRoles.model.js
module.exports = (sequelize, DataTypes) => {
const UserRoles = sequelize.define(
"user_roles",
{
role_id: {
type: DataTypes.INTEGER,
allowNull: false,
autoIncrement: true,
primaryKey: true,
unique: true,
},
role_name: {
type: DataTypes.STRING,
allowNull: false,
},
},
{
initialAutoIncrement: 100000,
}
);
// Method 02
UserRoles.associate = (models) => {
UserRoles.hasMany(models.Users, { as: "users", foreignKey: "user_id" });
};
return UserRoles;
};
My query is as follows:
findUser(body, callback) {
let jwt = new JsonWebToken();
let encrypted = crypto
.createHash("md5")
.update(body.password)
.digest("hex");
this.Users.findOne({
includes: [
model: 'user_roles'
]
where: {
user_email: body.email,
user_password: encrypted,
},
})
.then((res) => {
console.log(res)
})
.catch((err) => {
callback.status(302).send("Error Found" + err);
});
}
The error is throws as follows:
Error FoundSequelizeEagerLoadingError: user_roles is not associated to users!
Any help would be appreciated.
Thanks
doesn't matter if I try findOne() or findAll()
I get : []
empty array.
the query being called for findAll() is:
SELECT "id", "password", "firstName", "lastName", "email", "phone", "roleId", "userId", "createdAt", "updatedAt" FROM "Users" AS "Users";
while when I manually use in pgadmin cli this query: select * from Users;
I get all the rows of the table.
could you please advise?
const { Sequelize, DataTypes } = require('sequelize');
const sequelize = require('../db/database')
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
//console.log(sequelize);
const User = sequelize.define("Users", {
password: {
type: Sequelize.STRING,
allowNull: false,
validate:{
len: [8,40],
trim: true
}
},
firstName: {
type: Sequelize.STRING,
allowNull: false,
validate:{
len: [0,20],
trim: true,
lowercase: true
}
},
lastName: {
type: Sequelize.STRING,
allowNull: false,
validate:{
len: [0,20],
trim: true,
lowercase: true
}
},
email: {
type: Sequelize.STRING,
unique: true,
allowNull: false,
validate:{
len: [0,20],
trim: true,
lowercase: true,
isEmail: true
}
},
phone: {
type: Sequelize.STRING,
validate:{
len: [10,10],
trim: true,
}
},
roleId: {
type: Sequelize.INTEGER,
allowNull: false,
validate:{
trim: true
/* must convert roleId from string to integer
toInt(value){
return parseInt(value);
}*/
}
},
userId: {
type: Sequelize.INTEGER,
allowNull: false
}
},
{
timestamps: true,
versionKey: false,
hooks:{
beforeSave: async function(user,options){
if (user.isModified('password')) {
user.password = await bcrypt.hash(user.password, 8)
}
}
}
}
);
User.prototype.toJSON = function () {
const user = this;
const userObject = user.toObject();
delete userObject.password;
delete userObject.tokens;
return userObject;
};
User.prototype.generateAuthToken = async function () {
const user = this;
const payload = { user };
const token = jwt.sign(payload, process.env.ACCESS_TOKEN_SECRET, {
expiresIn: 360000
});
return token;
};
const findByCredentials = async (email, password) => {
const users= await User.findAll();
const user = await User.findOne({where: {email}});
if (!user) {
throw Error('invalid email');
}
const isMatch = await bcrypt.compare(password, user.password);
if (!isMatch) {
throw Error('invalid password');
}
return user;
}
User.sync();
module.exports = {
User,
findByCredentials
}
I am working on an eCommerce application, and I am trying to save users in my database but when I hit the API in the postmen then instead of :
res.json({
name: user.name,
email: user.email,
id: user._id
});
});
**instead of this code following code is running
user.save((err, user) => {
if (err) {
return res.status(400).json({
err: "NOT able to save user in DB"
});
}
//the complete code of my "auth.js" file is as following:
const User = require("../models/user");
exports.signup = (req, res) => {
const user = new User(req.body);
user.save((err, user) => {
if (err) {
return res.status(400).json({
err: "NOT able to save user in DB"
});
}
res.json({
name: user.name,
email: user.email,
id: user._id
});
});
};
exports.signout = (req, res) => {
res.json({
message: "User signout"
});
};
///and the complete code of my user model file is as following:
var mongoose = require("mongoose");
const crypto = require("crypto");
const uuidv1 = require("uuid/v1");
var userSchema = new mongoose.Schema(
{
name: {
type: String,
required: true,
maxlength: 32,
trim: true
},
lastname: {
type: String,
maxlength: 32,
trim: true
},
email: {
type: String,
trim: true,
required: true,
unique: true
},
userinfo: {
type: String,
trim: true
},
encry_password: {
type: String,
required: true
},
salt: String,
role: {
type: Number,
default: 0
},
purchases: {
type: Array,
default: []
}
},
{ timestamps: true }
);
userSchema
.virtual("password")
.set(function(password) {
this._password = password;
this.salt = uuidv1();
this.encry_password = this.securePassword(password);
})
.get(function() {
return this._password;
});
userSchema.methods = {
autheticate: function(plainpassword) {
return this.securePassword(plainpassword) === this.encry_password;
},
securePassword: function(plainpassword) {
if (!plainpassword) return "";
try {
return crypto
.createHmac("sha256", this.salt)
.update(plainpassword)
.digest("hex");
} catch (err) {
return "";
}
}
};
module.exports = mongoose.model("User", userSchema);
SO please anyone tell me how to solve this problem while hiting this code to api mongo shell is also opend and mean while i also keep ROBO3T connected.
I have created number of function in the user model which are both instance and class methods. But when i am calling class method findMyMobile() from a controller it is giving 'not a function' error. I tried display it inside the controller but it seems it is undefined there.
model/user.js
const { Sequelize, sequelize } = require('../db/sequelize');
const jwt = require('jsonwebtoken');
const Model = Sequelize.Model;
class User extends Model {}
User.init({
id:{
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
name: {
type: Sequelize.STRING,
allowNull: false
},
mobile_number:{
field:'mobile_number',
type: Sequelize.BIGINT(10),
unique:true,
allowNull: false,
is:/^[1-9]\d{9}$/g,
},
type:{
type: Sequelize.ENUM('0','1','2'),
allowNull: false,
defaultValue: '1',
},
otp:{
type: Sequelize.STRING,
},
createdAt: {
type: Sequelize.DATE,
allowNull: false,
defaultValue: Sequelize.NOW
},
updatedAt: {
type: Sequelize.DATE,
allowNull: false,
defaultValue: Sequelize.NOW
}
},{ sequelize,
modelName:'user',
classMethods:{
findByMobile: function(){
var User = this;
return User.findOne({'mobile_number':data['mobile_number']}).then(user => {
return new Promise((resolve,reject)=>{
if(user)
resolve(user);
else
reject(new Error('No user found'));
});
}).catch(err=>{
return Promise.reject(new Error('Database error'));
})
}
}
})
User.sync();
module.exports = {
User
}
controller/login.js
const { User } = require('../model/user');
const _ = require('lodash');
exports.login = (req, res) => {
const mobile = _.pick(req.body, ['mobile_number']);
console.log(typeof User.findByMobile);
User.findByMobile(mobile).then((user) => {
console.log(user);
}).catch(err => {
var response = {
status: 'failure',
message: err.message
}
res.send(response);
});
};
ERROR:
TypeError: User.findByMobile is not a function
Since sequelize v4 classMethods and instanceMethod are removed from the configuration options : https://sequelize.org/v4/manual/tutorial/upgrade-to-v4.html#config-options
You have two ways to define them
class User extends Model {
//Class Method
static findByMobile() {}
//Instance Method
findByMobile() {}
}
OR
class User extends Model { }
//Class Method
User.findByMobile = function() {}
//Instance Method
User.prototype.findByMobile = function() {}
I think you have the export wrong. See this example for reference.
module.exports = {
getName: () => {
return 'Jim';
},
getLocation: () => {
return 'Munich';
},
dob: '12.01.1982',
};
Then on the import file:
const { getName, dob } = require('./user');
console.log(
`${getName()} was born on ${dob}.`
);
What I do suggest is export the function itself. See link below for ref:
What is the purpose of Node.js module.exports and how do you use it?
In my case, one maincategory has many subcategories.
maincategory model defined:
const MainCategorySchema = mongoose.Schema({
mainCategoryName: {
type: String,
unique: true,
required: true,
},
});
subcategory model defined
const SubCategorySchema = mongoose.Schema({
subCategoryName: {
type: String,
unique: true,
required: true,
},
main_category: {
type: mongoose.Schema.Types.ObjectId,
ref: "MainCategory",
},
});
module.exports.getAllSubCategories = function (callback) {
SubCategory.find(callback);
};
route
router.get( "/subCategories",
passport.authenticate("jwt", { session: false }),
(req, res) => {
SubCategory.getAllSubCategories((err, subCategory) => {
if (err) {
let message = "No category";
return res.json({
success: false,
message,
});
} else {
return res.send(subCategory);
}
});
}
);
How can I display mainCategoryName along with subCategoryName?
You need to populate main_category like this:
router.get("/subCategories",
passport.authenticate("jwt", { session: false }), (req, res) => {
SubCategory.find()
.populate("main_category")
.exec((err, subCategory) => {
if (err) {
let message = "No category";
return res.json({
success: false,
message
});
} else {
return res.send(subCategory);
}
});
}
);