Search code examples
javascriptloopsstrapiiterable

How to iterate over the result of strapi.db.query?


I have a simple findMany query in my controller:

const appointments = strapi.db.query("api::appointment.appointment").findMany({
    select: ["date", "startTime", "endTime"],
    where: {
        mentorId: mentorId,
        status: [1, 2, 4]
    }
});

It returns the following, such structure made me think that the result returned is iterable.

[
    {
        "date":"2022-04-27",
        "startTime":"08:00:00.000",
        "endTime":"10:00:00.000"
    },
    {
        "date":"2022-04-27",
        "startTime":"10:00:00.000",
        "endTime":"12:00:00.000"
    }
]

However, when I use a for loop, I can tell that it didn't even enter since there's no output.

for (let appointment in appointments)
    console.log("I entered");

When I used forEach, I got error: appointments.forEach is not a function.

appointments.foreach(function(appointment) {
    console.log(appointment.date);
});

So, I then checked if it is iterable using Symbol.iterator in Object(appointments), but it returns false. Array.isArray(appointments) also returns false which is weird, because the result definitely looked like an array to me.

Is there any workaround for this? I need to loop through each object, and access its fields.

EDIT - Entire Controller File:

"use strict";

/**
 *  availability controller
 */

const { createCoreController } = require("@strapi/strapi").factories;

module.exports = createCoreController("api::availability.availability", ({strapi}) => ({
    async getFreeSlots(ctx) {
        const mentorId = ctx.params.mentorId;

        const appointments = strapi.db.query("api::appointment.appointment").findMany({
            select: ["date", "startTime", "endTime"],
            where: {
                mentorId: mentorId,
                status: [1, 2, 4]
            }
        });
        console.log(appointments);

        return appointments;
    }
}));

Solution

  • The .findMany() method is asynchronous and returns a Promise. I suppose you are instead trying to use it synchronously right after the call. You need to await it.

    const appointments = await strapi.db.query("api::appointment.appointment").findMany({
        select: ["date", "startTime", "endTime"],
        where: {
            mentorId: mentorId,
            status: [1, 2, 4]
        }
    });
    console.log(appointments);
    

    Alternatively, if you are not in an async function (that's needed to use await), you can use the classic .then() from the Promise:

    strapi.db.query("api::appointment.appointment").findMany({
        select: ["date", "startTime", "endTime"],
        where: {
            mentorId: mentorId,
            status: [1, 2, 4]
        }
    }).then((appointments) => {
        console.log(appointments);
        /*...*/
    });