当向数据库发送2个查询显示passport配置中存在字段时,发送2条flash消息
sending 2 flash messages when 2 queries to the databse show that fields exist in passport configuration
注册时,我会检查数据库,看看用户名和电子邮件是否存在。如果存在,应该会返回错误。所有用户名和电子邮件都应该是唯一的。我的问题似乎是我只能犯一个错误。如果电子邮件已经存在,我会收到快闪消息,但如果用户名也存在,它不会说明用户名已经存在。我想显示这两个错误如果两者都已经存在于张贴在一个闪光消息
我认为问题是返回电子邮件的done()
。由于我有两个查询,它只查看第一个被命中的查询。我真的不知道。
我试图对此进行研究,我知道你可以为req.flash传递一个数组,但我可以让它发挥作用,因为它会返回它看到的第一个存在的数组。
我还读到done
的第三个参数是一个信息对象,我认为它提供了关于用户的信息,我曾考虑加载那里的现有信息,但我无法将其组合在一起。我也试过其他东西。但我只向您展示查询数据库的方法,因为我在中失败得很厉害
passport.use("local-signup", new LocalStrategy({
usernameField : "email",
passwordField : "password",
passReqToCallback : true
},
function(req, email, password, done){
var arr = [];
User.findOne({"email" : email}, function(err, user){
if(err) return done(err);
if(user){
// arr.push("That email is already taken")
return done(null, false, req.flash("signupMessage", "That username is taken"))
}else{
User.findOne({"username" : req.body.username}, function(err,user){
if(err) return done(err);
if(user){
// arr.push()
return done(null, false, req.flash("signupMessage", "That username is taken"))
}else{
var newUser = new User();
newUser.username = req.body.username;
newUser.password = password;
newUser.email = req.body.email;
newUser.save(function(err, doc){
if(err) throw err;
console.log("doc", " " , doc)
return done(null, newUser);
})
}
})
}
})
}
))
EJS-
app.get("/signup", function(req, res){
console.log(req.session)
console.log(req.flash("signupMessage"))
res.render("signup", {authed : authed, user : user, message: req.flash("signupMessage")})
})
app.post("/signup",passport.authenticate("local-signup", {
successRedirect : "/",
failureRedirect : "/signup",
failureFlash : true
}))
这是一个基本的控制流问题。你回来了。不要。将不得不重复一些代码作为它的一个额外功能,或者使用一个标志并在之前命中数据库。也不确定你将如何显示这两条消息,将不得不单独解决。将它们合并为一个("用户名和电子邮件已注册。请输入不同的用户名和电子邮件id。")
User.findOne({"email" : email}, function(err, user){
if(err) return done(err);
if(user){
// arr.push("That email is already taken")
// do not know what all done does maybe a ligther versio that just sends the error
done(null, false, req.flash("signupMessage", "That Email is taken"))
User.findOne({"username" : req.body.username}, function(err,user){
if(err) return done(err);
if(user){
// arr.push()
return done(null, false, req.flash("signupMessage", "That username is taken"))
}//no else here
return;
}else{
User.findOne({"username" : req.body.username}, function(err,user){
if(err) return done(err);
if(user){
// arr.push()
return done(null, false, req.flash("signupMessage", "That username is taken"))
}else{
var newUser = new User();
newUser.username = req.body.username;
newUser.password = password;
newUser.email = req.body.email;
newUser.save(function(err, doc){
if(err) throw err;
console.log("doc", " " , doc)
return done(null, newUser);
})
}
})
}
})
}
))
调整控制流是解决此问题的一种方法,但如果您正在寻找更优雅的解决方案,则可以尝试promise.all()
方法。
promise.all()
所做的是,它实际上一次触发所有异步调用,并在何时返回;
- 所有异步调用都成功(解析)
- 异步调用中的任意1返回reject(失败)
显然,第2点并不是您想要的,因为您想要同时报告电子邮件和用户名,以应对它们不唯一的情况。
要解决此问题,您必须使用reflect
使promise.all()
仅在所有承诺都已回复(成功或失败)时返回。
考虑以下代码:
this.reflect = function reflect(promise){
return promise.then(function(/*resolve return value=*/v){ return { v:v, status: "resolved" }},
function(/*rejection error=*/e){ return { e:e, status: "rejected" }});
};
var promises = [
new Promise(function(resolve, reject) {
// User.findOne({"username" : req.body.username}, function(err,user){
// if (err) { return reject("error!"); }...
// resolve("Name is unique!!");
// });
resolve("name is unique");
}),
new Promise(function(resolve, reject) {
reject("email is NOT unique");
})
];
Promise.all(promises.map(this.reflect)).then(function(results) {
if (results[0].status === "rejected") {
console.log("Error reason: " + results[0].e);
}
else {
console.log("Succeeds, reason: " + results[0].v);
}
if (results[1].status === "rejected") {
console.log("Error reason: " + results[1].e);
}
else {
console.log("Succeeds, reason: " + results[1].v);
}
// You can call whatever callback you want here.
// e.g. return done(null, "Test");
});
输出:
成功,原因:名称唯一
错误原因:电子邮件不是唯一的
注意:您应该能够对上面的代码进行一些修改,以满足您的需求。如果你还有麻烦,就大声叫我。
参考:
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise
试试看:
var signupMessages = [];
User.findOne({"email" : email}, function(err, user){
if(err) return done(err);
if(user) signupMessages.push("That email is taken");
User.findOne({"username" : req.body.username}, function(err,user){
if(err) return done(err);
if(user) signupMessages.push("That username is taken");
if(signupMessages.length > 0){
return done(null, false, req.flash("signupMessage", signupMessages));
} else { ...
在这种情况下,req.flash("signupMessage")
将返回消息数组
- JSP 中的“日期”字段存在问题
- Ember-自定义计算属性,用于检查是否存在所有依赖字段
- 查询MongoDB中不存在的字段
- 我使用jquery创建输入字段,刷新页面后如何保持这个“新输入值”的存在
- json2html 当字段不存在时如何排除行
- 当文件输入中存在名称字段时,getElementById 不会发布
- 删除不存在的字段的子字段
- 有没有一种方法可以添加额外的独立字段,使它们不会成为预先存在的形式's(DOM)子代
- 将对象推送到mongoose数组,并检查数组对象中是否存在重复字段
- 不存在的属性HTML输入字段
- 验证可能不存在的字段
- 从字段中提取GUID(如果存在)
- 将段落中存在的各种文本输入字段的文本连接起来
- JS/MongoDB:检查对象(集合文档)中是否存在嵌套字段
- Meteor正在检测集合中是否存在字段
- 检查是否存在多个字段,如果不存在,则返回MongoDB中的所有项
- 从预先存在的字段生成ISO日期
- 在创建项之前,请检查字段值是否存在于其他SharePoint列表中
- Highstock.js / Angular.js中的范围选择器在xAxis配置字段存在时不会更新图表
- NodeJS:访问对象字段返回未定义,即使字段存在