System Information
- Strapi Version: 3.4.6
- Operating System: Windows 10
- Database: sqlite
- Node Version: 14.12.0
- NPM Version: 6.14.8
Hi,
I’m using Strapi Version 3.4.6 with a mutation “generateQuiz” to generate a quiz with a set of random questions from a pool of questions. In the controller I query all questions (inefficient, I know, but thats ok for the moment), shuffle the questions and pick the first x questions from the randomized list. When the questionpool contains less than x questions I would expect to get a quiz with a randomly sorted list of all available questions. Thats the case when I query the REST-API, but not when I query the GraphQL-API. GraphQL returns a quiz with questions always sorted by their ID.
Sample: Let’s assume we have a question pool of 9 questions (IDs 1 to 9) and we want to generate a quiz with a maximum of 10 questions. In the generateQuiz controller following happens:
- Query all (9) questions from the database
- Shuffle them
- take 10 out of the 9 questions → results in still 9 questions
- create a new quiz with the questions
- return
When I call the REST-API I get a quiz with the following list of questions for example: [5,3,2,8,6,1,4,9,7]
When I call the GraphQL-API I get always a quiz with a sorted list of the questions: [1,2,3,4,5,6,7,8,9]
Why is this the case? And can I change this behaviour?
Code
controller code:
async generateQuiz(ctx) {
const {questionCount, includeSubcategories} = ctx.request.body;
const categoryId = ctx.request.body.categoryId ? Number(ctx.request.body.categoryId) : undefined;
const userId = ctx.state.user.id;
let params = {
userId,
// eslint-disable-next-line camelcase
deadline_gte: new Date(),
// eslint-disable-next-line camelcase
finishedAt_null: true,
category: categoryId,
// eslint-disable-next-line camelcase
category_null: categoryId ? undefined : true
};
// remove undefined properties
params = _.pickBy(params, v => v !== undefined);
const quiz = await strapi.services.quiz.findOne(params);
if (quiz) {
throw strapi.errors['badRequest'](`An active quiz with categoryId ${categoryId} already exists. quizId: ${quiz.id}`);
}
let questions;
if (categoryId) {
const searchCategories = await strapi.services.category.list(categoryId, includeSubcategories);
const searchCategoryIds = _.map(searchCategories, 'id');
// eslint-disable-next-line camelcase
questions = await strapi.services['quiz-question'].find({category_in: searchCategoryIds}, []);
}
else {
if (includeSubcategories !== false) {
questions = await strapi.services['quiz-question'].find({}, []);
} else {
throw strapi.errors['badRequest'](`includeSubcategories cannot be set to false when no categoryId is specified`);
}
}
// get question IDs
let questionIds = _.map(questions, 'id');
// shuffle
questionIds = _.shuffle(questionIds);
// take first x question IDs
if (questionCount) {
questionIds = _.take(questionIds, questionCount);
}
strapi.log.debug('questionIds',questionIds);
// get number of questions
const quizQuestionCount = questionIds.length;
const now = _.now();
const deadline = now + (quizQuestionCount * strapi.config.get('server.app.secondsPerQuestionInQuiz', 60) * 1000);
const data = {
startedAt: now,
finishedAt: null,
deadline,
userId,
questions: questionIds,
category: categoryId
};
const newQuiz = await strapi.services.quiz.create(data);
strapi.log.debug('newQuiz question ids', _.map(newQuiz.questions,'id'));
return newQuiz;
},
graphql query:
mutation {
generateQuiz(questionCount: 15) {
id
questions {
id
}
}
}
sample console output:
[2021-02-18T08:56:14.622Z] debug questionIds [2,9,1,5,7,6,4,8,3]
[2021-02-18T08:56:14.711Z] debug newQuiz question ids [5,2,6,9,4,8,3,1,7]
graphql query result:
{
"data": {
"generateQuiz": {
"id": "91",
"questions": [
{
"id": "1"
},
{
"id": "2"
},
{
"id": "3"
},
{
"id": "4"
},
{
"id": "5"
},
{
"id": "6"
},
{
"id": "7"
},
{
"id": "8"
},
{
"id": "9"
}
]
}
}
}
api result (removed unnecessary data):
{
"id": 88,
...
"questions": [
{
"id": 5,
...
},
{
"id": 3,
...
},
{
"id": 2,
...
},
{
"id": 8,
...
},
{
"id": 6,
...
},
{
"id": 1,
...
},
{
"id": 4,
...
},
{
"id": 9,
...
},
{
"id": 7,
...
}
]
}
References:
BR, Stefan