I’m not sure if this is related to your issue or the cause of it but I’d like to put it here in case someone experiences something similar in the future.
I had an issue with this when using Strapi graphql plugin and I realized while the linked GitHub issue by Jim has been fixed, pagination total count was still broken. So it had to be from the Strapi graphql plugin. Turns out it was from the toEntityResponseCollection
method provided by the plugin, which works this way:
return toEntityResponseCollection(data, {
args,
resourceUID: entityType,
});
The method works well when you pass your query variables (args.filters
) as the only filters to your find operation. It doesn’t return the right count when you add an extra check or condition. This can be found in the graphql plugin code base here.
I got this to work by using the findWithCount method which returns the right count for me, passing it into the args object used by the toEntityResponseCollection
method, and extending the RESPONSE_COLLECTION_META_TYPE_NAME
type to use a total
value if available into the args object (otherwise default to the usual method).
In the register method of the index.js file
const extension = ({ nexus }) => ({
types: [
nexus.extendType({
type: RESPONSE_COLLECTION_META_TYPE_NAME,
definition(t) {
t.nonNull.field("pagination", {
type: PAGINATION_TYPE_NAME,
async resolve(parent) {
const { args, resourceUID } = parent;
const { start, limit, total } = args;
const safeLimit = Math.max(limit, 1);
// https://docs.strapi.io/dev-docs/backend-customization/controllers#sanitization-when-utilizing-controller-factories (You probably don't need this line in earlier versions of strapi and you can use args directly in place of sanitizedQuery)
const sanitizedQuery = await sanitize.contentAPI.query(args, parent.contentType, {
auth: ctx?.state?.auth,
});
const count =
total ||
(await strapi.entityService.count(resourceUID, sanitizedQuery));
const pageSize = limit === -1 ? count - start : safeLimit;
const pageCount =
limit === -1 ? safeLimit : Math.ceil(count / safeLimit);
const page =
limit === -1 ? safeLimit : Math.floor(start / safeLimit) + 1;
return { total: count, page, pageSize, pageCount };
},
});
},
}),
],
});
extensionService.use(extension);
Then in your resolver for your query - You can learn to extend queries and create resolvers in this article - return your data this way:
const transformedArgs = transformArgs(args, {
contentType: strapi.contentTypes[entityType],
usePagination: true,
});
const data = await strapi.db.query(entityType).findWithCount(filters);
return toEntityResponseCollection(data[0], {
args: {
// you can just spread the transformedArgs but I'm adding start and limit here for better visualization
start: transformedArgs.start,
limit: transformedArgs.limit,
total: data[1], // this will be returned if provided and you can pass the right count returned from findWithCount here
...transformedArgs,
},
resourceUID: entityType,
});