How do I update a schema array in MongoDB using mongoose? - node.js

Typically, I can query an item from MongoDB, change it like you would any other object, and call the save method to save it to the database. It won't work for my schema array, though. I don't have a lot of experience with this, so be gentle with me.
These are the relevant schema:
const bracketClicksSchema = new mongoose.Schema({
bracketID: String,
duo1Click: Boolean,
duo2Click: Boolean,
duo3Click: Boolean,
duo4Click: Boolean,
duo5Click: Boolean,
duo6Click: Boolean,
duo7Click: Boolean
});
const userSchema = new mongoose.Schema({
userId: String,
brackets: [bracketClicksSchema]
});
This is the user model:
const User = mongoose.model('User', userSchema);
This is how I'm trying to create a new user and populate the bracketClicksSchema array. The console.log() statements show that the object is being changed correctly, but calling it from the database again shows it hasn't actually saved to MongoDB.
app.post('/api/user', async (req, res) => {
let user = await User.findOne({
userId: req.body.id
});
if (user.brackets == null || user.brackets[0].bracketID != req.body.date1) {
user = new User({
userId: req.body.id,
brackets: [
{
bracketID: req.body.date1,
duo1Click: false,
duo2Click: false,
duo3Click: false,
duo4Click: false,
duo5Click: false,
duo6Click: false,
duo7Click: false
},
{
bracketID: req.body.date2,
duo1Click: false,
duo2Click: false,
duo3Click: false,
duo4Click: false,
duo5Click: false,
duo6Click: false,
duo7Click: false
},
{
bracketID: req.body.date3,
duo1Click: false,
duo2Click: false,
duo3Click: false,
duo4Click: false,
duo5Click: false,
duo6Click: false,
duo7Click: false
},
]
});
}
console.log("new user: " + user);
try {
await user.save();
res.send(user);
} catch (error) {
console.log(error);
}
// Check if saved successfully
user = await User.findOne({
userId: req.body.id
});
console.log("finding user again: " + user);
});
Console statements:
new user: {
userId: '1234',
brackets: [
{
bracketID: '2023-02-05',
duo1Click: false,
duo2Click: false,
duo3Click: false,
duo4Click: false,
duo5Click: false,
duo6Click: false,
duo7Click: false,
_id: new ObjectId("63e01fa1ae236745bf8ce09c")
},
{
bracketID: '2023-02-04',
duo1Click: false,
duo2Click: false,
duo3Click: false,
duo4Click: false,
duo5Click: false,
duo6Click: false,
duo7Click: false,
_id: new ObjectId("63e01fa1ae236745bf8ce09d")
},
{
bracketID: '2023-02-03',
duo1Click: false,
duo2Click: false,
duo3Click: false,
duo4Click: false,
duo5Click: false,
duo6Click: false,
duo7Click: false,
_id: new ObjectId("63e01fa1ae236745bf8ce09e")
}
],
_id: new ObjectId("63e01fa1ae236745bf8ce09b")
}
finding user again: {
_id: new ObjectId("63b9b3da9e19eabef4d4987b"),
userId: '1234',
brackets: null,
__v: 0
}
How do I successfully save the new user object I've created to MongoDB?

You forgot to populate('brackets')
// Check if saved successfully
user = await User.findOne({
userId: req.body.id
}).populate('brackets');
console.log("finding user again: " + user);

You are creating the new user with the same userId that is passed from the frontend. After that, multiple users with the same userId will exist in the database.
Since you are using findOne() query, only the first matched user will be returned.
Try to use find() query instead, and check if the new user is present in the array that you will get back.

Related

Node.js MongoError: E11000 duplicate key error collection:

Im working on a djs bot and i ran into an error that i dont know how to fix
i have looked at https://docs.mongodb.com/manual/indexes/ and NodeJs, Mocha and Mongoose
but nothing seems to help here is the info -
the error happens here -
const Data = await serverModel.findOne({ serverID: message.guild.id });
try{
console.log(`checking if a database exists for ${message.guild}`);
console.log(Data);
if(!Data) {
console.log(`Data base doent exist for ${message.guild}`);
console.log(`Creating a database for ${message.guild}`);
const server = await serverModel.create({
serverID: message.guild.id,
calling: 'no',
channel: null,
talkingWith: null,
stickyChannel: null,
stickyMessage: null,
stickyID: null,
});
console.log('shit');
server.save();
return;
}
}
catch(err) {
console.log(err);
}
this is my serverModel/serverSchema -
const mongoose = require('mongoose');
// ServerSchema
const ServerSchema = new mongoose.Schema({
serverID: { type: String, require: true, unique: true, sparse:true },
calling: { type: String, require: true, unique: false, sparse:true },
channel: { type: String, require: true, unique: false, sparse:true },
talkingWith: { type: String, require: true, unique: false, sparse:true },
stickyChannel: { type: String, require: true, unique: false, sparse:true },
stickyMessage: { type: String, require: true, unique: false, sparse:true },
stickyID: { type: String, require: true, unique: false, sparse:true },
});
const model = mongoose.model('ServerSchema', ServerSchema);
module.exports = model;
and lastly this is the error i get -
checking if a database exists for Vixo
null
Data base doent exist for Vixo
Creating a database for Vixo
MongoError: E11000 duplicate key error collection: database.serverschemas index: stickyChannel_1 dup key: { stickyChannel: null }
it seems like there are already records with 'stickyChannel' parameter as null value. So can you please try creating new records by simply assigning values to every parameter?
try following code for creating new record:
`const server = await serverModel.create(
{ serverID: message.guild.id,
calling: 'no',
channel: 'test',
talkingWith: 'test',
stickyChannel: 'test,
stickyMessage: 'test,
stickyID: 'test',
});`

Updating instance with multiple associations in Sequelize

I am able to create records in my MySQL DB with sequelize and NodeJS.
But now I am trying to update records in my Database.
I have NodeJS as backend and my DB is MySql. Sequelize is my ORM. In Sequelize 5, I have a couple of classes: WorkOder, User (mechanic), Customer, Client and ExpertiseOffice. My datamodel is not complex, there are only 1:1 relations. A WorkOrder has one customer, one Client and one ExpertiseOffice.
I use Postman to test my api's. With creating a WorkOrder with some Customer fields included the workOrder is created but not the Customer.
My associations file looks like this:
const User = require('../models/user');
const WorkOrder = require('../models/work-order');
const Customer = require('../models/customer');
const Client = require('../models/client');
const ExpertiseOffice = require('../models/expertise-office');
WorkOrder.belongsTo(User, { foreignKey: 'mechanicId' });
WorkOrder.belongsTo(Client, { foreignKey: 'clientId' });
WorkOrder.belongsTo(Customer, { foreignKey: 'customerId' });
WorkOrder.belongsTo(ExpertiseOffice, { foreignKey: 'expertiseOfficeId' });
The WorkOrder model looks like this:
// WORK-ORDER MODEL
const Customer = require('./customer');
const Client = require('./client');
const ExpertiseOffice = require('./expertise-office');
const User = require('./user');
const Sequelize = require('sequelize');
const sequelize = require('../util/database');
const WorkOrder = sequelize.define('workOrders', {
id: {
type: Sequelize.UUID,
allowNull: false,
primaryKey: true,
},
projectNumber: {
type: Sequelize.INTEGER,
allowNull: true,
},
dateInspection: {
type: Sequelize.DATE,
allowNull: true,
},
mechanicId: {
type: Sequelize.UUID,
allowNull: true,
references: {
// User belongsTo WorkOrder 1:1
model: 'User',
key: 'id',
},
},
clientId: {
// Opdrachtgever
type: Sequelize.UUID,
allowNull: true,
references: {
// Client belongsTo WorkOrder 1:1
model: 'Client',
key: 'id',
},
},
customerId: {
// klant
type: Sequelize.UUID,
allowNull: true,
references: {
// Customer belongsTo WorkOrder 1:1
model: 'Customer',
key: 'id',
},
},
expertiseOfficeId: {
type: Sequelize.UUID,
allowNull: true,
references: {
// ExpertiseOffice belongsTo WorkOrder 1:1
model: 'ExpertiseOffice',
key: 'id',
},
},
leakageReason: {
type: Sequelize.STRING,
allowNull: true,
},
status: {
type: Sequelize.STRING,
allowNull: true,
},
// Timestamps
createdAt: Sequelize.DATE,
updatedAt: Sequelize.DATE,
});
module.exports = WorkOrder;
In the front end application only very limited fields are required because the front end user can add information about the customer, client etc. on a later moment.
My WorkOrder controller with the updatre workOrder code (not working properly) is looking like this.
exports.updateWorkOrder = (req, res, next) => {
console.log('####-in the updateWorkOrder endpoint!');
const workOrder = req.body;
console.log('####-put-workorder', workOrder);
WorkOrder.update(
workOrder,
{ where: { id: req.params.id } },
{ include: [User, Customer, Client, ExpertiseOffice] }
)
.then((result) => {
if (result) {
WorkOrder.findByPk(req.params.id).then((result) => {
console.log('####--result', result);
console.log('####-work-order updated!');
res.status(200).json({
message: 'Work order successfully updated!',
data: result,
});
});
}
})
.catch((err) => {
console.log('error', err);
res.status(500).json({
message: 'An error occurred',
err: err,
});
});
};
The workOrder data which is going into the update method looks like this:
####-in the updateWorkOrder endpoint!
####-put-workorder {
id: '29d9795d-ef7f-418e-a479-340cb7ee5509',
projectNumber: '123456',
dateInspection: null,
followupInspection: null,
clientPresent: null,
mechanicId: null,
clientId: '2c611177-48f6-48d2-a2d0-e7f6a93cc16b',
customerId: 'd53f56c7-9954-4e52-b8e2-de4d28229caf',
expertiseOfficeId: null,
leakageReason: 'issue with roof',
visibleWaterDamage: null,
visibleWaterDamagePeriod: null,
buildingType: null,
renovatedYear: null,
status: null,
createdAt: '2020-07-04T07:24:28.000Z',
updatedAt: '2020-07-04T07:25:03.000Z',
user: null,
customer: {
id: 'd53f56c7-9954-4e52-b8e2-de4d28229caf',
name: 'Customer One',
contactPerson: null,
companyName: null,
street: 'Street',
houseNumber: '1',
houseNumberExt: null,
zipCode: '91111',
city: 'LA',
phoneNumber: null
},
client: {
id: '2c611177-48f6-48d2-a2d0-e7f6a93cc16b',
name: 'Roof Inspectors',
contactPerson: null,
email: null,
phoneNumber: 'Roof Inspectors',
street: null,
houseNumber: null,
houseNumberExt: null,
zipCode: null,
city: null,
attribute: null
},
expertiseOffice: null
}
This is the correct updated information from the front end.
Now I don't get an error message from sequelize but the record is not updated.
The spooled result looks like this:
####--result workOrders {
dataValues: {
id: '29d9795d-ef7f-418e-a479-340cb7ee5509',
projectNumber: '123456',
dateInspection: null,
followupInspection: null,
clientPresent: null,
mechanicId: null,
clientId: '2c611177-48f6-48d2-a2d0-e7f6a93cc16b',
customerId: 'd53f56c7-9954-4e52-b8e2-de4d28229caf',
expertiseOfficeId: null,
leakageReason: 'issue with roof',
visibleWaterDamage: null,
visibleWaterDamagePeriod: null,
buildingType: null,
renovatedYear: null,
status: null,
createdAt: 2020-07-04T07:24:28.000Z,
updatedAt: 2020-07-04T08:06:47.000Z
},
_previousDataValues: {
id: '29d9795d-ef7f-418e-a479-340cb7ee5509',
projectNumber: '123456',
dateInspection: null,
followupInspection: null,
clientPresent: null,
mechanicId: null,
clientId: '2c611177-48f6-48d2-a2d0-e7f6a93cc16b',
customerId: 'd53f56c7-9954-4e52-b8e2-de4d28229caf',
expertiseOfficeId: null,
leakageReason: 'issue with roof',
visibleWaterDamage: null,
visibleWaterDamagePeriod: null,
buildingType: null,
renovatedYear: null,
status: null,
createdAt: 2020-07-04T07:24:28.000Z,
updatedAt: 2020-07-04T08:06:47.000Z
},
_changed: {},
_modelOptions: {
timestamps: true,
validate: {},
freezeTableName: false,
underscored: false,
paranoid: false,
rejectOnEmpty: false,
whereCollection: { id: '29d9795d-ef7f-418e-a479-340cb7ee5509' },
schema: null,
schemaDelimiter: '',
defaultScope: {},
scopes: {},
indexes: [],
name: { plural: 'workOrders', singular: 'workOrder' },
omitNull: false,
sequelize: Sequelize {
options: [Object],
config: [Object],
dialect: [MysqlDialect],
queryInterface: [QueryInterface],
models: [Object],
modelManager: [ModelManager],
connectionManager: [ConnectionManager],
importCache: {}
},
hooks: {}
},
_options: {
isNewRecord: false,
_schema: null,
_schemaDelimiter: '',
raw: true,
attributes: [
'id',
'projectNumber',
'dateInspection',
'followupInspection',
'clientPresent',
'mechanicId',
'clientId',
'customerId',
'expertiseOfficeId',
'leakageReason',
'visibleWaterDamage',
'visibleWaterDamagePeriod',
'buildingType',
'renovatedYear',
'status',
'createdAt',
'updatedAt'
]
},
isNewRecord: false
}
Can anybody please help me? I have no clue why the records is not updated.
Many thanks in advance.
Pete

Mongoose unique property still allowing me to save to db

Im under the assumption that adding unique: true to a field would stop from saving to the database using the same value. But im still allowed to do it.
"mongoose": "^5.4.19",
const SessionSchema = new Schema({
jobId: {
type: String,
required: false,
unique: true,
index: true,
},
productId: {
type: String,
required: true,
},
status: {
type: String,
default: "Pending",
},
mode: {
type: String,
default: "authentication",
},
result: {
type: Schema.Types.Mixed,
},
requests: [RequestSchema],
callback_at: {
type: Date,
},
}, {
timestamps: { createdAt: "created_at", updatedAt: "updated_at" },
});
I have already tried deleting and recreating the collection. See the image below i can create new session with the same jobId being 1.
public store = async (req: Request, res: Response): Promise<any> => {
const input = req.body;
let session = new Session({
productId: input.productId,
jobId: input.jobId,
});
try {
session = await session.save();
const response = {
success: true,
status: 201,
data: { session },
message: "SESSION CREATED",
};
return res.status(response.status).json(response);
} catch (err) {
const response = {
success: false,
status: 500,
errors: [],
message: "UNEXPECTED SESSION ERROR",
};
if (err.code === 11000) {
response.errors.push({
code: 11000,
message: "Duplicate key error jobId",
});
}
return res.status(response.status).json(response);
}
db.sessions.getIndex();
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "myDB.sessions"
}
]
You have to understand that unique is an index configuration option in your schema.
For instance, if the users collection doesn't have a unique index on userName, then you need to wait for the index to build before you start relying on it.
const user = new mongoose.Schema({
userName: { type: 'String', unique: true },
});
const User = db.model('User', user);
const doc = new User({
userName: 'Bob'
});
return User.init() // `User.init()` returns a promise that is fulfilled when all indexes are done
.then(() => User.create(doc))
.then(() => User.create({ userName: 'Bob' }));
}
I was not using unique properly: https://mongoosejs.com/docs/validation.html#the-unique-option-is-not-a-validator
Need to wait until the indexes are built before relying on unique to be a validator.
I changed my mongoose connect options to look like the following
options: {
useNewUrlParser: true,
useCreateIndex: true,
autoIndex: true,
},
I;m not sure if its the most appropriate solution, but its the one ive gone with for now.

Get error when trying to register new user or log in

For some reason whenever I make a request to the routes to create a new user I get "This email account is already in use" although the user is created, and when I try to log in I get "The login information was incorrect". I console logged the req.body when logging in and I get the object logged and it seems okay.
My AuthenticationController.js
const {User} = require('../models')
const jwt = require('jsonwebtoken')
const config = require('../config/config')
function jwtSignUser (user) {
const ONE_WEEK = 60 * 60 * 24 * 7
return jwt.sign(user, config.authentication.jwtSecret, {
expiresIn: ONE_WEEK
})
}
module.exports = {
async register (req, res) {
try {
const user = await User.create(req.body)
const userJson = user.toJSON()
res.send({
user: userJson,
token: jwtSignUser(userJson)
})
} catch (err) {
res.status(400).send('This email account is already in use.')
}
},
async login (req, res) {
console.log(req.body)
try {
const {email, password} = req.body
const user = await User.findOne({
where: {
email: email
}
})
if (!user) {
return res.status(403).send({
error: 'The login information was incorrect'
})
}
const isPasswordValid = await user.comparePassword(password)
if (!isPasswordValid) {
return res.status(403).send({
error: 'The login information was incorrect'
})
}
const userJson = user.toJSON()
res.send({
user: userJson,
token: jwtSignUser(userJson)
})
} catch (err) {
res.status(500).send({
error: 'An error has occured trying to log in'
})
}
}
}
console.log(user) gives me the following:
User {
dataValues:
{ id: 41,
username: 'testing',
email: 'testing#gmail.com',
password:
'$2a$08$J6/psKuCltiCpCll2rjz4OaCylud0zq/wKnjKK8Udmm.bFU3c2Tt6',
firstName: 'test',
lastName: 'ing',
createdAt: 2019-02-26T15:47:09.133Z,
updatedAt: 2019-02-26T15:47:09.133Z },
_previousDataValues:
{ id: 41,
username: 'testing',
email: 'testing#gmail.com',
password:
'$2a$08$J6/psKuCltiCpCll2rjz4OaCylud0zq/wKnjKK8Udmm.bFU3c2Tt6',
firstName: 'test',
lastName: 'ing',
createdAt: 2019-02-26T15:47:09.133Z,
updatedAt: 2019-02-26T15:47:09.133Z },
_changed: {},
_modelOptions:
{ timestamps: true,
validate: {},
freezeTableName: false,
underscored: false,
underscoredAll: false,
paranoid: false,
rejectOnEmpty: false,
whereCollection: { email: 'testing#gmail.com' },
schema: null,
schemaDelimiter: '',
defaultScope: {},
scopes: [],
indexes: [],
name: { plural: 'Users', singular: 'User' },
omitNull: false,
hooks:
{ beforeCreate: [Array],
beforeUpdate: [Array],
beforeSave: [Array] },
sequelize:
Sequelize {
options: [Object],
config: [Object],
dialect: [SqliteDialect],
queryInterface: [QueryInterface],
models: [Object],
modelManager: [ModelManager],
connectionManager: [ConnectionManager],
importCache: [Object],
test: [Object] },
uniqueKeys: { Users_email_unique: [Object] } },
_options:
{ isNewRecord: false,
_schema: null,
_schemaDelimiter: '',
raw: true,
attributes:
[ 'id',
'username',
'email',
'password',
'firstName',
'lastName',
'createdAt',
'updatedAt' ] },
__eagerlyLoadedAssociations: [],
isNewRecord: false }
console.log(req.body) gives me this:
{ email: 'testing#gmail.com',
password: 'testing99',
username: 'testing',
firstName: 'test',
lastName: 'ing' }
They have the same information but it gives me an error anyway.
I assume you are using mongoose, according to the documentation https://mongoosejs.com/docs/api.html#model_Model.findOne findOne is returning Query object, so validation may fail.
Check with debugger or even simple console.log to see what's inside of the user variable in login function.
So if user does not exist, you are getting Query object which is not empty, because mongoose filled this object with some functions.
You can try to use lean(), checkout this article http://www.tothenew.com/blog/high-performance-find-query-using-lean-in-mongoose-2/
We have 2 solution here:
Using raw: true
const user = await User.findOne({
where: {
email: email
},
raw: true
})
Using plain: true
user = user.get({
plain: true
});

Sequelize instance methods not working

I am trying to use Sequelize's instance method to validate a password on login attempt.
I have defined the User model as :
var User = sequelize.define('User',{
id:{
type:DataTypes.BIGINT,
autoIncrement: true,
allowNull: false,
primaryKey:true
},
username:{
type:DataTypes.STRING,
unique:true
},
password:{
type: DataTypes.STRING
},
...
},
{
classMethods:{
associate:function(models){
...
}
}
},
{
instanceMethods:{
validatePassword:function(password){
return bcrypt.compareSync(password, this.password);
}
}
}
);
return User;
}
In my login route I do the following :
1) Retrieve username & password from request body
2) Check if username exists in database
3) If user exists, get user object and compare sent password with hashed password in database using validatePassword method.
Here is the relevant code
var username = req.body.username || "";
var password = req.body.password || "";
models.User.findOne({ where: {username: username} }).
then(
function(user) {
if(user){
console.log(user.validatePassword(password));
}
....
Each time I try to login I get the following error
[TypeError: user.validatePassword is not a function]
What am I doing wrong?
I think you are using the sequelize model definition api incorrectly.
http://docs.sequelizejs.com/en/latest/docs/models-definition/#expansion-of-models
This is the correct way:
var User = sequelize.define('User',{}, {
classMethods: {
method1: ...
},
instanceMethods: {
method2: ...
}
});
not like this:
var User = sequelize.define('User',{}, {
classMethods: {
method1: ...
}
},{
instanceMethods: {
method2: ...
}
});
For anyone who's having a similar problem, I ran into the same issue but using Sequelize 5.21.5. According to this article, Sequelize Instance Methods, starting with Sequelize 4.0 and above, you have to use the prototype methodology in order to define instance methods like so:
// Adding an instance level methods.
User.prototype.validPassword = function(password) {
return bcrypt.compareSync(password, this.password);
};
We can add instanceLevelMethods to prototype,
User.prototype.your-instance-level-method-name = function() {
return 'foo';
};
I did it like this:
// Adding an instance level methods.
User.prototype.validPassword = function(password) {
return bcrypt.compareSync(password, this.password);
};
I use this approach:
const bcrypt = require('bcrypt-nodejs');
const constants = require('../constants/users');
module.exports = (Sequelize, type) => {
const User = Sequelize.define(constants.TABLE_NAME, {
username: {
type: type.STRING,
unique: true,
allowNull: false,
},
password: {
type: type.STRING,
allowNull: false,
},
// bla bla
});
const setSaltAndPassword = async function(user) {
if (user.changed('password')) {
const salt = bcrypt.genSaltSync(constants.PASSWORD_SALT_SIZE);
user.password = bcrypt.hashSync(user.password, salt);
}
};
User.prototype.validPassword = async function(password) {
return await bcrypt.compare(password, this.password);
};
User.beforeCreate(setSaltAndPassword);
User.beforeUpdate(setSaltAndPassword);
return User;
};
as at sequelize "sequelize": "^5.21.7" accessing the instanceMethods as shown by #user1695032 returns undefined.
here's what i found after several hours of getting undefined in the console.log() passing in the user object return from the query below:
User {
dataValues: {
id: 1,
firtName: null,
lasteName: null,
email: 'ugbanawaji.ekenekiso#ust.edu.ng',
phone: null,
password: '$2b$10$yEWnBFMAe15RLLgyU3XlrOUyw19c4PCmh8GJe9QVz3YkbdzK5fHWu',
createdAt: 2020-05-27T21:45:02.000Z,
updatedAt: 2020-05-27T21:45:02.000Z
},
_previousDataValues: {
id: 1,
firtName: null,
lasteName: null,
email: 'ugbanawaji.ekenekiso#ust.edu.ng',
phone: null,
password: '$2b$10$yEWnBFMAe15RLLgyU3XlrOUyw19c4PCmh8GJe9QVz3YkbdzK5fHWu',
createdAt: 2020-05-27T21:45:02.000Z,
updatedAt: 2020-05-27T21:45:02.000Z
},
_changed: {},
**_modelOptions: {**
timestamps: true,
validate: {},
freezeTableName: false,
underscored: false,
paranoid: false,
rejectOnEmpty: false,
whereCollection: { email: 'ugbanawaji.ekenekiso#ust.edu.ng' },
schema: null,
schemaDelimiter: '',
defaultScope: {},
scopes: {},
indexes: [],
name: { plural: 'Users', singular: 'User' },
omitNull: false,
**instanceMethods: { comparePasswords: [Function: comparePasswords] },**
hooks: { beforeValidate: [Array] },
sequelize: Sequelize {
options: [Object],
config: [Object],
dialect: [MysqlDialect],
queryInterface: [QueryInterface],
models: [Object],
modelManager: [ModelManager],
connectionManager: [ConnectionManager],
importCache: [Object]
}
},
_options: {
isNewRecord: false,
_schema: null,
_schemaDelimiter: '',
raw: true,
attributes: [
'id', 'firtName',
'lasteName', 'email',
'phone', 'password',
'createdAt', 'updatedAt'
]
},
isNewRecord: false
}
the code before the error:
models.User.findOne({where: {email: req.body.email}}).then((user)=>{
console.log(user)
if(!user) {
res.status(401).json({ message: 'Authentication failed!' });
} else {
user.comparePasswords(req.body.password, (error, isMatch) =>{
console.log(error + ' -- ' + isMatch)
if(isMatch && !error) {
const token = jwt.sign(
{ username: user.username },
keys.secret,
{ expiresIn: '30h' }
);
res.status(200).json({ success: true,message: 'signed in successfully', token: 'JWT ' + token });
} else {
res.status(401).json({ success: false, message: 'Login failed!' });
}
});
}
}).catch((error)=>{
console.log(error)
res.status(500).json({ success: false, message: 'There was an error!'});
})
this cause TypeError: user.comparePasswords is not a function
after changing this line:
** user.comparePasswords(req.body.password, (error, isMatch) =>{} **
to this:
** user._modelOptions.instanceMethods.comparePasswords(req.body.password, (error, isMatch) =>{}**
booooom! everything worked

Resources