nestjsx / nestjs-typeorm-paginate

:page_with_curl: Pagination response object function + types for typeorm + nestjs

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[bug] paginate Error 🐞

gavin-c-tcg opened this issue · comments

use SelectQueryBuilder and join 2 table and TAKE_AND_SKIP

pageinate.mate.totalItems will return raw of number, is error

it must return count of only master table

like this
1.[items,count ] =selectQueryBuilder.take(10).skip(20).getManyAndCount()
2. example

export const paginate = async <T>(builder: SelectQueryBuilder<T>, opt: IOptions) => {
  builder.take(opt.limit).skip((opt.page - 1) * opt.limit);
  const [items, count] = await builder.getManyAndCount();

  return {
    items,
    mate: {
      totalItems: count,
      itemCount: items.length,
      itemsPerPage: opt.limit,
      totalPages: Math.ceil(count / opt.limit),
      currentPage: opt.page,
    },
  };
};

I Fixed this issue by following code which overrides the createPaginationObject before paginate function call

import { createPaginationObject, IPaginationMeta, IPaginationOptions, IPaginationOptionsRoutingLabels, paginate as defaultPaginate, Pagination } from 'nestjs-typeorm-paginate'
import * as page from 'nestjs-typeorm-paginate/dist/create-pagination'
import { FindManyOptions, FindOptionsWhere, ObjectLiteral, Repository, SelectQueryBuilder } from 'typeorm'

const oldCreatePaginationObject = createPaginationObject

async function overrideCount(queryObj) {
  const count = await queryObj.getCount()

  function overrideCreatePaginationObject<T, CustomMetaType extends ObjectLiteral = IPaginationMeta>(params: {
    items: T[]
    totalItems?: number
    currentPage: number
    limit: number
    route?: string
    metaTransformer?: (meta: IPaginationMeta) => CustomMetaType
    routingLabels?: IPaginationOptionsRoutingLabels
  }): Pagination<T, CustomMetaType> {

    // after this override, remaining calculation will be resume as same as previous
    params.totalItems = count

    return oldCreatePaginationObject(params)
  }

  (page.createPaginationObject as any) = overrideCreatePaginationObject
}

function revertOverride() {
  (page.createPaginationObject as any) = oldCreatePaginationObject
}

async function paginate<T, CustomMetaType = IPaginationMeta>(
  repositoryOrQueryBuilder: Repository<T> | SelectQueryBuilder<T>,
  options: IPaginationOptions<CustomMetaType>,
  searchOptions?: FindOptionsWhere<T> | FindManyOptions<T>,
): Promise<Pagination<T, CustomMetaType>> {
  if (repositoryOrQueryBuilder instanceof Repository) {
    return await defaultPaginate<T, CustomMetaType>(repositoryOrQueryBuilder, options, searchOptions)
  }

  await overrideCount(repositoryOrQueryBuilder)
  const result = await paginate<T, CustomMetaType>(repositoryOrQueryBuilder, { ...options, countQueries: false })
  revertOverride()

  return result
}

export { paginate }

Now import paginate from this module and replace with package paginate function

For me it only happened when using the queryBuilder. I had to use the paginationType TAKE_AND_SKIP and use the getCount() method from queryBuildder.

You can use this patch which solved it for me. Use it at your own risk.

diff --git a/node_modules/nestjs-typeorm-paginate/dist/paginate.js b/node_modules/nestjs-typeorm-paginate/dist/paginate.js
index 3d28819..943ced5 100644
--- a/node_modules/nestjs-typeorm-paginate/dist/paginate.js
+++ b/node_modules/nestjs-typeorm-paginate/dist/paginate.js
@@ -134,15 +134,13 @@ function paginateQueryBuilder(queryBuilder, options) {
     return __awaiter(this, void 0, void 0, function* () {
         const [page, limit, route, paginationType, countQueries, cacheOption] = resolveOptions(options);
         const promises = [
-            (interfaces_1.PaginationTypeEnum.LIMIT_AND_OFFSET === paginationType
-                ? queryBuilder.limit(limit).offset((page - 1) * limit)
-                : queryBuilder.take(limit).skip((page - 1) * limit))
-                .cache(cacheOption)
-                .getMany(),
+            queryBuilder.take(limit).skip((page - 1) * limit)
+            .cache(cacheOption)
+            .getMany(),
             undefined,
         ];
         if (countQueries) {
-            promises[1] = countQuery(queryBuilder, cacheOption);
+            promises[1] = queryBuilder.getCount();
         }
         const [items, total] = yield Promise.all(promises);
         return (0, create_pagination_1.createPaginationObject)({

I just hit this issue this morning, when selecting 56 records with 2 joins, I get a total of 80, but I am using v3.2.1 as the project is on old TypeORM.

Is this fixed in a newer release as that would give me cause to upgrade :)

any news?

@gavin-c-tcg or @bashleigh , please consider closing this issue as a duplicate of 627.