i want use a function recursive to look if the usernames exist in mongodb with mongoose and nodejs.
I use the callback, but i don't understand why my function return undefined result. Could you help Me ?
Thanks ;)
var mongoose = require('mongoose');
var debug = require('debug')('gc:model:User');
var UserSchema = new Schema({
username: {type: String, required: true, trim: true, index: {unique: true, dropDups: true}},
email: {type: String, trim: true},
role: {type: String, required: true, default: 'user'},
});
generateUsername = function (username, number) {
'use strict';
var i = 0;
var usernames = [];
usernames.push(username);
while (i < number) {
var count = parseInt(usernames[i].substr(-1));
if (count >= 0) {
count += 1;
} else {
count = 0;
}
usernames.push(usernames[i].substring(0, count === 0 ? usernames[i].length : usernames[i].length - 1) + count);
i++;
}
return usernames;
};
findUniqueUsername = function (usernames, cb) {
'use strict';
if (usernames.length === 0) {
return cb(null);
}
// If one of the username is undefined, go the next one
if (typeof usernames[0] === 'undefined') {
usernames.shift();
findUniqueUsername(usernames);
}
_db.User.findOne({'username': usernames[0]}).exec(function (err, user) {
if (err) return cb(err);
if (user) {
debug('Bu ! => ', usernames[0]);
usernames.shift();
findUniqueUsername(usernames);
}
else {
debug('GooD ! => ', usernames[0]); // Value OK i have
return usernames[0]; // Value Not OK undefined :(
}
});
};
var namestart = "jobs";
var usernameTries = generateUsername(namestart, 100);
var username = findUniqueUsername(usernameTries); // is undefined
The variable username
will stay undefined, as you are preforming an async call.
If you start by generating 100 usernames, you can query all of them, and then filter out the non-existing. You can still use this recursive, by calling findUniqueUsernames
again and passing the callback.
'use strict';
const mongoose = require('mongoose');
let UserSchema = new Schema({
username: {
type: String,
required: true,
trim: true,
index: {
unique: true,
dropDups: true}
},
email: {
type: String,
trim: true
},
role: {
type: String,
required: true,
default: 'user'
},
});
var generateUsernames = function (username, number) {
let usernames = new Array(number - 1)
.fill(username)
.map((username, index) => username + index);
usernames.unshift(username);
return usernames;
};
var findUniqueUsernames = function (usernames, callback) {
if (usernames.length === 0) return callback(null, null);
_db.User.find({
username: {
$in: usernames
}
})
.select('username')
.exec((err, results) => {
if (err) return callback(err, null);
else {
let existingUsernames = results.map(r => r.username);
let uniqueUsernames = usernames
.filter(username => existingUsernames.indexOf(username) < 0);
return callback(null, uniqueUsernames);
// as an alternative, you could check here,
// if uniqueUsernames.length === 0
// and use findUniqueUsernames recursive by passing the same callback again
// return findUniqueUsernames(newSetOfPossibleUsernames, callback)
}
});
};
var namestart = 'jobs';
var usernameTries = generateUsernames(namestart, 100);
findUniqueUsernames(usernameTries, (err, uniqueUsernames) => {
if (err) {
console.log(err);
} else {
console.log(uniqueUsernames);
}
});
In a more mongoosie world, I would make findUniqueUsernames at least a static method of UserSchema:
UserSchema.statics.findUniqueUsernames = function( ...
and replace _db.User.find( ...
with
this.find( ...
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments