Skip to content

Commit e08b291

Browse files
committed
add filtration and update readme
1 parent 316557b commit e08b291

File tree

4 files changed

+126
-17
lines changed

4 files changed

+126
-17
lines changed

README.md

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,86 @@
1818

1919
```bash
2020
npm install @tfarras/nestjs-typeorm-pagination
21-
```
21+
```
22+
23+
24+
### Pagination Query params
25+
26+
* `_start` - from which row to start on fetch
27+
* `_limit` - how many rows to take
28+
* `_sortBy`? - column for sorting
29+
* `_order`? - order for sorting. Accepted values: `1 | -1 | ASC | DESC`
30+
31+
### Filtration
32+
33+
You can filter your data by passing columns and values as query params.
34+
For the moment we support `Equal` and `In` operator of typeorm.
35+
36+
#### Usage of `Equal`
37+
To filter data with `Equal` operator, you can simply add a parameter like `column=value`
38+
39+
Examples:
40+
<br/>
41+
`id=1` <br/>
42+
`email=farrastaimoor@gmail.com` <br />
43+
`country=MD`
44+
45+
#### Usage of `In`
46+
To filter data with `In` operator, you can add more than one time parameter like `column=value`
47+
48+
Examples:
49+
<br />
50+
`id=1&&id=2&&id=3` <br />
51+
`country=MD&&country=SE&&country=US`
52+
53+
<hr>
54+
55+
### Usage
56+
57+
Extend your entity from `PaginateableBaseEntity` :
58+
```typescript
59+
@Entity({ name: 'user' })
60+
export class UserEntity extends PaginateableBaseEntity {
61+
```
62+
63+
Add parameter decorator to your controller method :
64+
```typescript
65+
@Get()
66+
getMany(
67+
@PgParams() pg: PaginationParams,
68+
) {...}
69+
```
70+
71+
And now you're able to use pagination:
72+
```typescript
73+
...
74+
import { PgParams, PaginationParams, Pagination } from '@tfarras/nestjs-typeorm-pagination';
75+
76+
@Get()
77+
getMany(
78+
@PgParams() pg: PaginationParams,
79+
): Promise<Pagination<UserEntity>> {
80+
return UserEntity.findAndPaginate(pg);
81+
}
82+
```
83+
84+
Example request:
85+
```
86+
/user?_limit=11&_start=0&_sortBy=id&_order=DESC&id=1&id=2&email=farrastaimoor@gmail.com
87+
```
88+
89+
`Pagination` response:
90+
```json
91+
{
92+
"data": [
93+
{
94+
"id": 2,
95+
"email": "farrastaimoor@gmail.com",
96+
"firstname": "Taimoor",
97+
"lastname": "Farras",
98+
"country": "MD",
99+
}
100+
],
101+
"total": 1,
102+
}
103+
```

src/paginateable.entity.ts

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
import { BadRequestException } from '@nestjs/common';
2-
import { BaseEntity, ObjectType, FindManyOptions } from 'typeorm';
2+
import { BaseEntity, ObjectType, FindManyOptions, In, Equal } from 'typeorm';
33
import { PaginationParams } from './pagination.decorator';
44
import { Pagination } from './pagination.interface';
55

66
export abstract class PaginateableBaseEntity extends BaseEntity {
7-
87
/**
98
* Finds entities that match given find options
109
*/
@@ -15,33 +14,57 @@ export abstract class PaginateableBaseEntity extends BaseEntity {
1514
): Promise<Pagination<T>> {
1615
const entity = this as any;
1716
const {
18-
_end,
17+
_limit,
1918
_start,
2019
_order,
21-
_sort,
20+
_sortBy,
21+
_filter,
2222
} = pg;
2323
let query = options;
24-
const columnExists = entity.getRepository().metadata.findColumnWithPropertyPath(_sort);
24+
const columnExists = entity.getRepository().metadata.findColumnWithPropertyPath(_sortBy);
2525

26-
if (_order && _sort && columnExists) {
26+
if (_order && _sortBy && columnExists) {
2727
query = {
2828
...query,
2929
order: {
30-
[_sort]: _order,
30+
[_sortBy]: _order,
3131
}
3232
}
3333
}
3434

35-
if (_start >= 0 && _end > _start) {
35+
if (_start >= 0 && _limit > 0) {
3636
query = {
3737
...query,
38-
take: _end - _start,
38+
take: _limit,
3939
skip: _start,
4040
}
4141
} else {
4242
throw new BadRequestException('Invalid pagination query!');
4343
}
4444

45+
if (_filter) {
46+
const toFilter = Object.entries(_filter).filter(([key]) =>
47+
entity.getRepository().metadata.findColumnWithPropertyPath(key)
48+
);
49+
const filterQuery = {};
50+
51+
toFilter.forEach(([key, value]) => {
52+
if (Array.isArray(value)) {
53+
filterQuery[key] = In(value);
54+
} else {
55+
filterQuery[key] = Equal(value);
56+
}
57+
});
58+
59+
query = {
60+
...query,
61+
where: {
62+
...query.where,
63+
...filterQuery,
64+
}
65+
}
66+
}
67+
4568
const [data, total] = await entity.getRepository().findAndCount(query as any);
4669

4770
return {

src/pagination.decorator.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,28 @@
11
import { createParamDecorator } from '@nestjs/common';
2+
import { ObjectLiteral } from 'typeorm';
23

34
export interface PaginationParams {
4-
_end: number;
5+
_limit: number;
56
_start: number;
67
_order?: 'ASC' | 'DESC' | 1 | -1;
7-
_sort?: string;
8+
_sortBy?: string;
9+
_filter: ObjectLiteral;
810
}
911

1012
export const PgParams = createParamDecorator((data, req): PaginationParams => {
1113
const {
12-
_end,
14+
_limit,
1315
_start,
1416
_order,
15-
_sort,
17+
_sortBy,
18+
..._filter
1619
} = req.query;
1720

1821
return {
19-
_end: +_end,
22+
_limit: +_limit,
2023
_start: +_start,
2124
_order,
22-
_sort,
25+
_sortBy,
26+
_filter,
2327
};
2428
});

src/pagination.interface.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ import { PaginateableBaseEntity } from './paginateable.entity';
33
export interface Pagination<T extends PaginateableBaseEntity> {
44
data: T[];
55
total: number;
6-
}
6+
}

0 commit comments

Comments
 (0)