我有以下模型:
/**
* @module optikos
*/
const mongoose = require('mongoose');
/**
* Define the schema of the main table(Document)
* Needs to be redefined to add user role here
*/
const dbUri = 'mongodb://localhost:27017/optikosmaindb';
mongoose.connect(dbUri,{ useNewUrlParser: true });
const optikosSchema = mongoose.Schema({
name: {
type: String
},
email: {
type: String,
required:[true,'Email is required']
},
password: {
type: String,
required:[true,'Password is required']
},
dbpath: {
type: String,
required:true
},
role:{
type:String,
lowercase:true,
enum:{
values:['admin','employee','shop owner'],
message:'`${VALUE} is not a valid role`'
},
default:'shop owner'
},
payment_status: {
/***
* Only show owners need to have a payment status
*/
required:this.role == 'shop owner',
type: String,
lowercase:true,
enum:{
values:['pending','paid'],
message:'`{VALUE} is not a valid payment status`'
},
default: 'pending' //will change to paid once a payment transaction is completed
},
payment_reset: {
required:this.role == 'shop owner',
type: Date,
default:Date.now
}
});
const Optikos = mongoose.model('optikos',optikosSchema);
module.exports = Optikos;
我还有一个名为index.js
的文件,在其中需要这样的文件才能为我的数据库创建一些用户:
const admins = require('./admins');
const Optikos = require('../schemas/optikos');
const bcrypt = require('bcrypt');
async function setup() {
console.log('Setting app Optikos main database');
try {
let registeredAdmins = admins.map(async admin=>{
let {email,name,password} = admin;
let role = 'admin';
let saltRounds = 10;
password = await bcrypt.hash(password,saltRounds);
let dbpath = dbUri;
let user = new Optikos({
'name':name,
'email':email,
'password':password,
'role':role,
'dbpath':dbpath
});
return user;
});
let response = await Optikos.create(registeredAdmins);
console.log('Registered admins')
process.exit(0);
} catch (e) {
console.log('Error error error')
console.log(e)
process.exit(1)
}
}
setup();
admins文件是包含名称,电子邮件和密码字段的对象数组。但是,在尝试运行index
文件后,我得到以下信息:“ {ValidationError:optikos验证失败:dbpath:Path {{ 1}}是必需的。,密码:需要密码,电子邮件:需要电子邮件”。但是,如果我记录了要传递给“ new Optikos()”的所有变量,则会得到期望的值。这是怎么回事?
答案 0 :(得分:1)
我通过执行以下操作解决了必填字段错误:
let registeredAdmins = admins.map(async admin=>{
let {email,name,password} = admin;
let role = 'admin';
let saltRounds = 10;
password = await bcrypt.hash(password,saltRounds);
let dbpath = dbUri;
let user = new Optikos({
'name':name,
'email':email,
'password':password,
'role':role,
'dbpath':dbpath
});
return user;
});
Promise.all(registeredAdmins)
.then(async users=>{
console.log(users)
await Optikos.create(users);
console.log('Yeap')
}).catch(e=>{
console.log(e)
})
由于registeredAdmins是一个promise列表,因此我使用Promise.all()来获取已解决promise的值。感谢@AbdullahDibas作为提示
答案 1 :(得分:0)
通常是由于async await
在经常循环的情况下无法按预期的方式工作的事实(尽管for-await-in
的另一种替代方法是,但仍未被认为是可以保证生产安全,或符合某些eslint标准的良好做法),因此,您可能希望将代码改写为:
const admins = require('./admins');
const Optikos = require('../schemas/optikos');
const bcrypt = require('bcrypt');
async function setup() {
console.log('Setting app Optikos main database');
const passwordPromises = [];
try {
admins.forEach(admin => {
let { password } = admin;
let saltRounds = 10;
passwordPromises.push(bcrypt.hash(password, saltRounds));
});
const passwords = await Promise.all(passwordPromises);
let registeredAdmins = admins.map((admin, index) => {
let { email, name } = admin;
let user = new Optikos({
'name': name,
'email': email,
// The below would work because Promise.all resolves them in
// the sequential order. Also, since there would be a one - to - one
// mapping in the indices of the admins and the password due to the above stated fact
// the following would work
'password': passwords[index],
'role': 'admin',
'dbpath': dbUri
});
return user;
});
let response = await Optikos.create(registeredAdmins);
console.log('Registered admins')
process.exit(0);
} catch (e) {
console.log('Error error error')
console.log(e)
process.exit(1)
}
}