I'm trying to check that a username is unique, and I gather that I'd need a custom validation for that. I've written the following code, but instead of returning the error in the array returned by .validate()
, it just throws the error, which isn't the behaviour described in the docs and isn't what I want.
var User = sequelize.define('User', {
username: {
type: DataTypes.STRING,
validate: {
isUnique: function (username) {
User.find({ where: { username: username }})
.done(function (err, user) {
if (err) {
throw err;
}
if (user) {
throw new Error('Username already in use');
}
});
}
}
},
The validation you are doing is asynchronous. You call the User.find
method, and after that the validation method returns. Sequelize has no way of knowing that you are doing something async in your validation, unless you tell it so. Once your find call is done you throw the error, but the validation has completed, so there is no code to catch that error, which means the error is thrown and crashes the app
The way to tell sequelize that you are doing something async is to take a second argument to your function, which is a callback. If you call the callback without any arguments, the validation succeeded, if you give it an argument, the validation failed.
var User = sequelize.define('User', {
username: {
type: DataTypes.STRING,
validate: {
isUnique: function (username, done) {
User.find({ where: { username: username }})
.done(function (err, user) {
if (err) {
done(err);
}
if (user) {
done(new Error('Username already in use'));
}
done();
});
}
}
},
Could you point me to the part of the documentation that mislead you, then we can hopefully correct it :)
Sequelize supports Promise style async operations. Specifically the Bluebird.js lib. Just change your function to specifically use the Promise -> next()
pattern.
var User = sequelize.define('User', {
username: {
type: DataTypes.STRING,
validate: {
isUnique: function (username) {
User.find({ where: { username: username }})
.then(function (user) {
if (user) {
throw new Error('Username already in use');
}
});
}
}
},
This will also handle any errors on User.find()
for you.
See this example in their codebase
Of course the easiest way to handle unique constraints is by setting unique: true
on the field definition itself:
var User = sequelize.define('User', {
username: {
type: DataTypes.STRING,
unique: true
},
But this requires that you are either creating the table using Sequelize or already have a table with the unique constraint set.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With