From 46232de7f0d65007f491612786d77d4a01ca5aa7 Mon Sep 17 00:00:00 2001 From: Toast Date: Sun, 2 Feb 2025 17:48:21 +0100 Subject: [PATCH 1/5] Rework default behaviour for pagination --- src/pagination.dto.ts | 4 ++-- src/shows/shows.service.ts | 5 +---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/pagination.dto.ts b/src/pagination.dto.ts index fbdd2e1..5c06ec3 100644 --- a/src/pagination.dto.ts +++ b/src/pagination.dto.ts @@ -6,10 +6,10 @@ export class PaginationDto { @IsNumber() @Type(() => Number) @Min(1) - page?: number = 1; + page?: number; @IsOptional() @IsNumber() @Type(() => Number) @Min(1) - limit?: number = 1; + limit?: number; } diff --git a/src/shows/shows.service.ts b/src/shows/shows.service.ts index 76189f8..dc92c32 100644 --- a/src/shows/shows.service.ts +++ b/src/shows/shows.service.ts @@ -14,11 +14,8 @@ export class ShowsService { } async findAll(page: number, showsPerPage: number): Promise { - // Default value is 1 and I can't think any reason why you would want - // a single item per page, so if showsPerPage is 1 then just don't do - // any pagination at all let shows; - if (showsPerPage != 1) { + if (showsPerPage !== undefined) { const skip = (page - 1) * showsPerPage; shows = await this.showModel.find().skip(skip).limit(showsPerPage); } else { From 7a2913023438c48f7787c6b8aae62b7ae8680012 Mon Sep 17 00:00:00 2001 From: Toast Date: Sun, 2 Feb 2025 18:08:53 +0100 Subject: [PATCH 2/5] Shows/service: search regex in title AND description --- src/shows/shows.service.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/shows/shows.service.ts b/src/shows/shows.service.ts index dc92c32..5becbcd 100644 --- a/src/shows/shows.service.ts +++ b/src/shows/shows.service.ts @@ -34,7 +34,10 @@ export class ShowsService { async search(name: string) { const regex = new RegExp(name, 'i'); - return this.showModel.find({ title: { $regex: regex } }); + const filter = { + $or: [{ title: { $regex: regex } }, { description: { $regex: regex } }], + }; + return this.showModel.find(filter); } async update(id: string, dto: ShowDto): Promise { From f2190117842d6a9fe697a6fc603423ae74981a52 Mon Sep 17 00:00:00 2001 From: Toast Date: Sun, 2 Feb 2025 18:29:48 +0100 Subject: [PATCH 3/5] Shows/service: get search document count from db --- src/shows/shows.controller.ts | 10 +++++++--- src/shows/shows.service.ts | 5 ++++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/shows/shows.controller.ts b/src/shows/shows.controller.ts index 86e4ca1..9d06964 100644 --- a/src/shows/shows.controller.ts +++ b/src/shows/shows.controller.ts @@ -88,9 +88,13 @@ export class ShowsController { async search(@Query() search: SearchDto) { try { const { query } = search; - const shows = await this.showsService.search(query); - if (shows.length > 0) { - return { status: 'Ok', show: shows, test: shows.length }; + const serviceResponse = await this.showsService.search(query); + if (serviceResponse.showCount > 0) { + return { + status: 'Ok', + shows: serviceResponse.shows, + showCount: serviceResponse.showCount + }; } else { throw new NotFoundException({ status: 'Error', diff --git a/src/shows/shows.service.ts b/src/shows/shows.service.ts index 5becbcd..b7e543b 100644 --- a/src/shows/shows.service.ts +++ b/src/shows/shows.service.ts @@ -37,7 +37,10 @@ export class ShowsService { const filter = { $or: [{ title: { $regex: regex } }, { description: { $regex: regex } }], }; - return this.showModel.find(filter); + return { + shows: await this.showModel.find(filter), + showCount: await this.showModel.find(filter).countDocuments() + }; } async update(id: string, dto: ShowDto): Promise { From 65797b924343be73722bd62f8e9347ccfdda99ef Mon Sep 17 00:00:00 2001 From: Toast Date: Sun, 2 Feb 2025 18:45:36 +0100 Subject: [PATCH 4/5] Shows: add pagination to search endpoint --- src/shows/shows.controller.ts | 12 +++++++++--- src/shows/shows.service.ts | 14 +++++++++++--- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/shows/shows.controller.ts b/src/shows/shows.controller.ts index 9d06964..84d606e 100644 --- a/src/shows/shows.controller.ts +++ b/src/shows/shows.controller.ts @@ -85,15 +85,21 @@ export class ShowsController { } @Get('search') - async search(@Query() search: SearchDto) { + async search(@Query() search: SearchDto, @Query() pagination: PaginationDto) { try { const { query } = search; - const serviceResponse = await this.showsService.search(query); + const { page, limit } = pagination; + + const serviceResponse = await this.showsService.search( + query, + page, + limit, + ); if (serviceResponse.showCount > 0) { return { status: 'Ok', shows: serviceResponse.shows, - showCount: serviceResponse.showCount + showCount: serviceResponse.showCount, }; } else { throw new NotFoundException({ diff --git a/src/shows/shows.service.ts b/src/shows/shows.service.ts index b7e543b..4e7a475 100644 --- a/src/shows/shows.service.ts +++ b/src/shows/shows.service.ts @@ -32,14 +32,22 @@ export class ShowsService { return this.showModel.findById(id); } - async search(name: string) { + async search(name: string, page: number, showsPerPage: number) { const regex = new RegExp(name, 'i'); const filter = { $or: [{ title: { $regex: regex } }, { description: { $regex: regex } }], }; + let shows; + + if (showsPerPage !== undefined) { + const skip = (page - 1) * showsPerPage; + shows = await this.showModel.find(filter).skip(skip).limit(showsPerPage); + } else { + shows = await this.showModel.find(filter); + } return { - shows: await this.showModel.find(filter), - showCount: await this.showModel.find(filter).countDocuments() + shows: shows, + showCount: await this.showModel.find(filter).countDocuments(), }; } From 094c7388de70c40fcd42d83fd900211537e43a9b Mon Sep 17 00:00:00 2001 From: Toast Date: Sun, 2 Feb 2025 18:45:53 +0100 Subject: [PATCH 5/5] Format pagination dto --- src/pagination.dto.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pagination.dto.ts b/src/pagination.dto.ts index 5c06ec3..59c33f1 100644 --- a/src/pagination.dto.ts +++ b/src/pagination.dto.ts @@ -1,5 +1,5 @@ -import { Type } from "class-transformer"; -import { IsNumber, IsOptional, Min } from "class-validator"; +import { Type } from 'class-transformer'; +import { IsNumber, IsOptional, Min } from 'class-validator'; export class PaginationDto { @IsOptional()