Skip to content

2. Custom Decorator untuk Injected created_by

Sebelumya kita sudah berhasil menyimpan kategori ke dalam database dan berhasil menambahkan id user pada field created_by.

kategori.service.ts
async create(payload: CreateKategoriDto): Promise<ResponseSuccess> {
    try {
      await this.kategoriRepository.save({
        ...payload,
        created_by: {    
          id: this.req.user.id,
        },
      });

      return this._success('OK', this.req.user.user_id);
    } catch {
      throw new HttpException('Ada Kesalahan', HttpStatus.UNPROCESSABLE_ENTITY);
    }
  }

Pada kode di atas terlihat jika kita mengambil id user dari request token JWT. Sebenarnya dengan cara seperti itu tidak ada masalah, namun akan merepotkan jika membuat kode yang sama pada setiap service pada aplikasi kita. Pada materi ini kita akan membuat custom decorator agar kita tidak perlu menambahkan created_by pada payload yang akan disimpan di service.

1. Membuat Custom Decorator Inject Created_By

Custom Decorator InjectCreatedBy bertujuan untuk menambahkan created_by pada payload yang dikirim oleh client.

utils/decorator/inject-created_by.decorator.ts
import { createParamDecorator, ExecutionContext } from '@nestjs/common';

export const InjectCreatedBy = createParamDecorator(
  (data: any, ctx: ExecutionContext) => {
    const req = ctx.switchToHttp().getRequest();

    req.body.created_by = { id: req.user.id };

    return req.body;
  },
);

2. Menambahkan created_by dan updated_by pada DTO

Kita tambahkan created_by dan updated_by pada KategoriDto agar ditambahkan sebagai data yand kirim oleh clinet

kategori.dto.ts
import { OmitType } from '@nestjs/mapped-types';
import { IsInt, IsObject, IsOptional, IsString } from 'class-validator';
import { PageRequestDto } from 'src/utils/dto/page.dto';

export class KategoriDto {
  @IsInt()
  id?: number;

  @IsString()
  nama_kategori: string;

  @IsObject()
  @IsOptional()
  created_by: { id: number };

  @IsObject()
  @IsOptional()
  updated_by: { id: number };
}

export class CreateKategoriDto extends OmitType(KategoriDto, [
  'id',
  'updated_by',
]) {}  // ketika create kecualikan id , dan updated_by

export class UpdateKategoriDto extends OmitType(KategoriDto, ['created_by']) {} 
export class findAllKategori extends PageRequestDto {
  @IsString()
  @IsOptional()
  nama_kategori: string;
}

3. Implementasikan pada method create

kategori.controller.ts
import { Body, Controller, Get, Post, UseGuards } from '@nestjs/common';
import { KategoriService } from './kategori.service';
import { CreateKategoriDto, findAllKategori } from './kategori.dto';
import { JwtGuard } from '../auth/auth.guard';
import { Pagination } from 'src/utils/decorator/pagination.decorator';
import { InjectCreatedBy } from 'src/utils/decorator/inject-created_by.decorator'; //import disini

@UseGuards(JwtGuard)
@Controller('kategori')
export class KategoriController {
  constructor(private kategoriService: KategoriService) {}

  @Post('create')
  async create(@InjectCreatedBy() payload: CreateKategoriDto) { //ganti @Body() dengan @InjectCreatedBy()
    return this.kategoriService.create(payload);
  }

  @Get('list')
  async getAllCategory(@Pagination() query: findAllKategori) {
    return this.kategoriService.getAllCategory(query);
  }
}
kategori.service.ts
 async create(payload: CreateKategoriDto): Promise<ResponseSuccess> {
    try {
      await this.kategoriRepository.save(payload);  // cukup payload tanpa manipulasi object

      return this._success('OK', this.req.user.user_id);
    } catch {
      throw new HttpException('Ada Kesalahan', HttpStatus.UNPROCESSABLE_ENTITY);
    }
  }

4.Pengujian pada Postman

Alt text

5. Cek Tabel Kategori

Alt text

Terlihat jika hasilnya sama seperti sebelumnya, created_by berhasil tersimpan ke database.