I'm trying to make questionList
a global variable so both router.post can use it because questionList
use aggregate to take 10 random objects from a database, but it keeps having this error:
(node:17008) UnhandledPromiseRejectionWarning: TypeError: questionList is not iterable
const mongodb = require('mongodb');
const express = require('express');
const router = express.Router();
const app = express();
app.use(express.urlencoded());
app.use(express.json());
var questionList = async function (req, res, next) {
next();
const questionList = await req.database
.collection('questions')
.aggregate([{ $sample: { size: 10 } }])
.toArray();
return questionList;
};
app.use(questionList);
router.post('/attempts', async (req, res) => {
let correctAnswers = {};
for (const questions of questionList) {
correctAnswers[questions._id] = questions.correctAnswer;
}
let attemptQuiz = {
questions: questionList,
correctAnswers,
completed: false,
startAt: new Date(),
};
let newAttemptQuiz = await req.database
.collection('attempts')
.insertOne(attemptQuiz);
let renderAttemptsQuiz = await req.database
.collection('attempts')
.findOne({ _id: mongodb.ObjectID(`${newAttemptQuiz.insertedId}`) });
const quesShow = renderAttemptsQuiz.questions;
let objAll = [];
let quest = {};
for (const part of quesShow) {
quest._id = part._id;
quest.text = part.text;
quest.answers = part.answers;
objAll.push(quest);
}
let responseAttempt = {
_id: renderAttemptsQuiz._id,
questions: objAll,
completed: false,
startAt: new Date(),
};
res.status(200).json(responseAttempt);
});
router.post('/attempts/submit', async (req, res) => {
let correctAnswers = {};
for (const questions of questionList) {
correctAnswers[questions._id] = questions.correctAnswer;
}
const clientAnswers = req.body;
const count = 0;
for (const ques of questionList) {
if (correctAnswers[ques._id] == clientAnswers[ques._id]) {
count ;
}
}
res.json({ score: count });
});
module.exports = router;
Please help me fix this!! Thanks very much
CodePudding user response:
You will need to cache your response in another variable.
let sample = []
var questionList = async function (req, res, next) {
sample = await req.database
.collection('questions')
.aggregate([{ $sample: { size: 10 } }])
.toArray()
next()
};
for (const ques of sample) {
if (correctAnswers[ques._id] == clientAnswers[ques._id]) {
count ;
}
}
Уou can also stash it in the request object.
var questionList = async function (req, res, next) {
req._sample = await req.database
.collection('questions')
.aggregate([{ $sample: { size: 10 } }])
.toArray()
next()
};
for (const ques of req._sample) {
if (correctAnswers[ques._id] == clientAnswers[ques._id]) {
count ;
}
}
Also, install your middleware on the router.
router.use(questionList);
// app.use(questionList);