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

`paginate` is inconsistent with `findAndCount` behavior

Garfield550 opened this issue · comments

A look at the source code shows that the paginate method uses typeorm's findAndCount method.

const [items, total] = await repository.findAndCount({

But their behavior is inconsistent.

When using the same FindConditions parameter { siteInfo: { id: sid } }, the result of findAndCount is correct:

this.siteConfigRepository.findAndCount({ siteInfo: { id: sid } });
{
  "data": [
    [
      {
        "language": "en-US",
        "timezone": "UTC+8",
        "theme": "landscape",
        "domain": "www.example.com",
        "createdAt": "2021-08-02T10:14:53.664Z",
        "updatedAt": "2021-08-02T10:14:53.664Z",
        "id": 1
      },
      {
        "language": "en-US",
        "timezone": "UTC+0",
        "theme": "hoho",
        "domain": "aaa.example.com",
        "createdAt": "2021-08-02T10:16:12.681Z",
        "updatedAt": "2021-08-02T10:16:12.681Z",
        "id": 2
      }
    ],
    2
  ],
  "statusCode": 200,
  "message": "Ok"
}

The paginate method, however, returns data containing the wrong relationship:

paginate<SiteConfigEntity>(this.siteConfigRepository, options, { siteInfo: { id: sid } });
{
  "data": {
    "items": [
      {
        "language": "en-US",
        "timezone": "UTC+8",
        "theme": "landscape",
        "domain": "www.example.com",
        "createdAt": "2021-08-02T10:14:53.664Z",
        "updatedAt": "2021-08-02T10:14:53.664Z",
        "id": 1
      },
      {
        "language": "en-US",
        "timezone": "UTC+0",
        "theme": "hoho",
        "domain": "aaa.example.com",
        "createdAt": "2021-08-02T10:16:12.681Z",
        "updatedAt": "2021-08-02T10:16:12.681Z",
        "id": 2
      },
      {
        "language": "en-US",
        "timezone": "UTC+8",
        "theme": "landscape",
        "domain": "www.example.com",
        "createdAt": "2021-08-02T10:19:21.934Z",
        "updatedAt": "2021-08-02T10:19:21.934Z",
        "id": 3
      }
    ],
    "meta": {
      "totalItems": 3,
      "itemCount": 3,
      "itemsPerPage": 10,
      "totalPages": 1,
      "currentPage": 1
    },
    "links": {
      "first": "/site/config?limit=10",
      "previous": "",
      "next": "",
      "last": "/site/config?page=1&limit=10"
    }
  },
  "statusCode": 200,
  "message": "Ok"
}

The correct way is:

paginate<SiteConfigEntity>(this.siteConfigRepository, options, { where: { siteInfo: { id: sid } } });

By looking at the type definition of findAndCount, I found that FindManyOptions and FindConditions conflict with each other:

findAndCount(options?: FindManyOptions<Entity>): Promise<[Entity[], number]>;
findAndCount(conditions?: FindConditions<Entity>): Promise<[Entity[], number]>;

I think should check if the searchOptions is an instance of FindManyOptions or FindConditions:

const [items, total] = await repository.findAndCount({
skip: limit * (page - 1),
take: limit,
...searchOptions,
});

I can see the diff yea, guess I should update the docs to use FindConditions instead of FindManyOptions? I've found some issues with these two types myself. Or should I force the use of FinsConditions opposed to FindManyOptions?

I prefer FindManyOptions because it can declare relations.

FindManyOptions extends FindOneOptions, and FindOneOptions.where is FindConditions.

https://github.com/typeorm/typeorm/blob/a868078f8f4f63cc8d81a63e098d639ed12c6608/src/find-options/FindOneOptions.ts#L16-L19

 /**
   * Simple condition that should be applied to match entities.
   */
 where?: FindConditions<Entity>[]|FindConditions<Entity>|ObjectLiteral|string;

Yea that's a fair point! Would you like to make this PR for the next major release?

Okay.