我正在开发一个允许用户参与民意调查的小应用程序,但是我在查看当前用户是否已经在投票中投票时遇到了问题。其他一切正常,除了检查所述条件的IIFE,如包含的代码片段所示。实际上,我得到false
而不是true
我拥有的数据,即我已经在数据库中播放了样本数据,包括随机轮询,其中包含已经用户的ID数组投票。我尝试针对所述数组测试一个ID,它返回false而不是预期的true。是什么赋予了?
以下是相关摘录。
模型
import mongoose from 'mongoose';
const Schema = mongoose.Schema;
const ChoiceSchema = new Schema({
name: { type: String },
votes: { type: Number }
});
const PollSchema = new Schema({
title: { type: String },
category: { type: String },
choices: [ChoiceSchema],
addedBy: { type: Schema.Types.ObjectId, ref: 'User' },
votedBy: [{ type: Schema.Types.ObjectId, ref: 'User' }]
});
const Poll = mongoose.model('Poll', PollSchema);
export default Poll;
控制器
import Poll from '../models/poll';
export default {
fetchAllPolls: async (req, res) => {
/*...*/
},
fetchSpecificPoll: async (req, res) => {
/*...*/
},
voteInPoll: async (req, res) => {
const { category, pollId } = req.params;
const { name, choiceId, voterId } = req.body;
try {
const poll = await Poll.findById(pollId);
const choice = await poll.choices.id(choiceId);
const votedChoice = {
name,
votes: choice.votes + 1,
};
// Check if user has already voted in poll
const hasVoted = ((votersIds, id) => votersIds.includes(id))(
poll.votedBy,
voterId
);
if (!voterId) {
res
.status(400)
.json({ message: 'Sorry, you must be logged in to vote' });
} else if (voterId && hasVoted) {
res.status(400).json({ message: 'Sorry, you can only vote once' });
} else {
await choice.set(votedChoice);
await poll.votedBy.push(voterId);
poll.save();
res.status(200).json({
message: 'Thank you for voting. Find other polls at: ',
poll,
});
}
} catch (error) {
res.status(404).json({ error: error.message });
}
},
createNewPoll: async (req, res) => {
/*...*/
},
};
答案 0 :(得分:1)
poll.votedBy
很可能不是ID字符串数组。如果您将它用作参考字段,那么它是一个BSON对象数组,使用includes
将失败,因为它使用sameValueZero算法来比较值。如果确实如此,那么您可以先将所有ID转换为字符串,也可以使用find
和equals
方法查找匹配项。
此外,some
将提供一种更简单的方法来返回布尔值。
const hasVoted = poll.votedBy.some((voter) => voter.equals(voterId));
答案 1 :(得分:1)
我认为您正在尝试将ObjectId与表示mongo id的String进行比较。
这应该有效:
const hasVoted = ((votersIds, id) => votersIds.findIndex((item) => item.toString() === id) !== -1)(
poll.votedBy,
voterId
);
或
const hasVoted = ((votersIds, id) => votersIds.findIndex((item) => item.equals(new ObjectId(id))) !== -1)(
poll.votedBy,
voterId
);
修改
正如@JasonCust建议的那样,一个更简单的形式应该是:
const hasVoted = poll.votedBy.some(voter => voter.equals(voterId));