Tuesday 3 August 2021

Sequelize findAndCountAll pagination issue

When using findAndCountAll with a limit and offset, I get only (for example) 8 rows per page instead of 10.

Here's what I'm using to paginate results (10 per page):

async function allPlayers(req, res) {
  const page = parseInt(req.query.page);
  const perPage = parseInt(req.query.perPage);

  const options = {
    where: {
      [Op.and]: [
        {
          type: "player",
        },
        {
          "$teams.team.type$": "club",
        },
      ],
    },
    include: [
      {
        model: UserTeam,
        duplicating: false,
        required: true,
        include: [
          {
            model: Team,
            include: [{ model: Club }, { model: School }],
          },
        ],
      },
    ],
  };

  const { rows, count } = await User.findAndCountAll({
    ...options,
    limit: perPage,
    offset: perPage * (page - 1),
  });

  res.json({ data: { rows, count } });
}

The issue seems to be Sequelize filtering out the rows when returned from SQL, instead of in the query. This happens because of this segment in the find options query:

{
  model: UserTeam,
  duplicating: false,
  required: true,
  include: [...],
}

Because of that, instead of returning 10 per paginated page, it's returning 10 or less (depending if any rows were filtered out).

Is there a fix for this behaviour or a different way to re-structure my data so I don't need this nested query?

I need this because I have a database/model structure like this:

User (players, coaches, admins, etc.)
  |
  |_ UserTeam (pivot table containing userId and teamId)
    |
    |_ Team


from Sequelize findAndCountAll pagination issue

No comments:

Post a Comment