Skip to main content

Filter and count rows in Nestjs & MYSQL database

In the earlier tutorial, you learnt to connect NestJs app with MYSQL database and do migration to add new column to the product table. Now we move on creating APIs to filter data by name with counting the number of products, by id, and delete a specific product from the database. 

Execute the following commands to create products module, controller, and service in products folder:


npx nest g module products

npx nest g controller products

npx nest g service products

Update products/products.module.ts file to specify the products repository used in the current scope using forFeature method. 

import { TypeOrmModule } from '@nestjs/typeorm';
import { Product } from 'src/entities/product.entity';
import { ProductsController } from './products.controller';
import { ProductsService } from './product.service';
@Module({
  imports: [TypeOrmModule.forFeature([Product])],
  controllers: [ProductsController],
  providers: [ProductService],
  exports: [ProductService]
})
export class ProductModule {}

Then, we can use @InjectRepository to inject Product Repository to the ProductsService. Also mention ProductsService to the exports list to make it available to the ProductsController.

Update products/products.service.ts file to create products repository instance and define findWithLimit, and fineOne, and remove methods to  filter product data with skip and take parameters, get product by id, and remove product from database. The findAndCount is a convenient method of Repository to return all rows match the search query and count the number of matched rows by ignoring skip and take.

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Product } from 'src/entities/product.entity';
import { InsertResult, Like, Repository } from 'typeorm';

@Injectable()
export class ProductsService {
  constructor(
    @InjectRepository(Product)
    private prouctsRepository: Repository<Product>,
  ) {}
 

  findWithLimit(start:number, limit:number,search:string): Promise<[Product[],number]> {
    const c1=search?  {name: Like(`%${search}%`)}:null;
    return this.prouctsRepository.findAndCount(
      {
        where:c1,
        skip: start,
        take:limit
       
      }
    );
  }

  findOne(id: number): Promise<Product> {
    return this.prouctsRepository.findOneBy({ id });
  }

  async remove(id: string): Promise<void> {
    await this.prouctsRepository.delete(id);
  }
}

Update the products/products.controller.ts file to define products controller. The first route  /products using Get method accepts one query string  - product id to fetch product by id. In NestJs, to use Res and Req objects in a method you need to specify @Req() and @Res() in the method. The second route /products/all using Get method filters products data by name. It accepts start, limit, and search query strings. The third route /products/{id} using Delete method removes a product specified by id from the database.

import { Controller,Get, Post,Req, Header,Put, Delete,Query,Param,Body,
, Res} from '@nestjs/common';

import { Product } from 'src/entities/product.entity';

import { ProductsService } from 'src/products/products.service';


@Controller('products')

export class ProductsController {
    constructor(private productsService: ProductsService) {}

    @Get() /* /products?id=... */
    async findById(@Req() req,@Res() res, @Query() query) {
   
      if(query.id){
        const pro=await this.productsService.findOne(query.id);
        res.send({data:pro});
      }
      else{
        res.send({});
      }

    }
 
    @Get('all') /* /products/all */
    async findLimit(@Res() res, @Query('start') start, @Query('limit') limit,@Query('search') search) {

        const result=await this.productsService.findWithLimit(start,limit,search);
        res.send({
            status:200,
            data:result

        });
        /
    }


    @Delete(':id') /* /products/{id} */
    remove(@Param('id') id: string) {
     this.productsService.remove(id);
    }
 
}



To test the APIs, let insert few sample product data to the product table. Execute the following command to create a migration file:

npx typeorm migration:create  ./src/migrations/InsertProductData

Open the migration file to add query to insert two rows to the table:

import { MigrationInterface, QueryRunner } from "typeorm"

export class InsertProductData1666058643395 implements MigrationInterface {

    public async up(queryRunner: QueryRunner): Promise<void> {
        await queryRunner.query(

            `INSERT INTO
            product (name, description, price, thumbnail, user)
            VALUES
            ('Fresh Banana','Best selling fresh banana',1.0,'fbanna.png',1),
            ('Milk Rice','Best selling milk rice from Cambodia ',1.0,'cmrice.png',1)
       
        `);
    }

    public async down(queryRunner: QueryRunner): Promise<void> {
    }

}

Finally execute the command below to run the migration to insert two products to the product table in the database.

npx typeorm-ts-node-commonjs migration:run -d src/data-source.ts 

There are various tools to test APIs. In this tutorial, we use ARC chrome extension. Add the ARC to chrome and from chrome://apps launch ARC.

To get all products, select method GET and the Request Url is http://localhost:3000/products/all.




Get product with id equal to 20: http://localhost:3000/products?id=20.

Get only first one product: http://localhost:3000/products/all?start=0&limit=1.

Filter products by name containing rice: http://localhost:3000/products/all?search=rice.

Get only first one product in which its name contains rice:
http://localhost:3000/products/all?start=0&limit=1&search=rice.

To delete a specific product from the database. Let say product with id 20. You need to select method DELETE and the Request Url is http://localhost:3000/products/20.

Comments

Popular posts from this blog

Nestjs & Angular

NestJs is currently a popular server-side framework from Node. It is a useful tool to build secure and high performance enterprise-level applications. NestJs built on top of Express and Fastify is influenced by Angular (front-end framework) and OOP (Object-Oriented Programming).  With NestJs, you can build applications in any size with scalability with TypeScript and JavaScript . Your large applications can be divided in to different modules . Each module may have its own controllers ,  providers and services .  A Controller manages requests and responses. The route system maps the controller to specific request actions. The Controller frequently has more than one route.  A provider can be a service, factory, or helper class that can be injected as dependency so you create various relationships of different parts of your applications. Commonly we used providers to manage user authentication and authorization  and data sources from Mysql, PostgreSQL, MongoDB, ...

Upload form data with image file in NestJs & MYSQL

 In the previous tutorial, you learned how to filter and count rows in NestJs with TypeORM & MYSQL database . This tutorial teaches you how to upload form data in NestJs & MYSQL. We will create two more routes to insert and update product data. A client app is able to submit form data with an image file. The max image file size in byte is 200000 and it must be jpg, jpeg, png, or gif type.  To upload files in NestJs, it is required to install Multer typings package. npm install @types/multer Create public/uploads folder in the nestjs project to store uploaded files. Then, update the products/ProductsController.tsx file to add the following code: ............................. import { UseInterceptors, ParseFilePipe , FileTypeValidator ,     MaxFileSizeValidator , UploadedFile } from '@nestjs/common' ; import { Express } from 'express' ; import { diskStorage } from 'multer' ; import * as path from 'path' ; import { Product } from ...