so I am creating a backend service using nest js I am following the dto pattern now I created a product dto like this:
import { OmitType } from "@nestjs/mapped-types";
import { Product } from "../entities/product.entity";
import {AutoMap} from '@automapper/classes'
import { ApiProperty } from "@nestjs/swagger";
export class CreateProductDto{
@AutoMap()
@ApiProperty()
productId: string;
@AutoMap()
@ApiProperty()
productName: string;
@AutoMap()
@ApiProperty()
price: number;
@AutoMap()
@ApiProperty()
userId: string;
}
and the entity like this:
import { v4 as uuid } from 'uuid';
import { BaseEntity, Column, Double, Entity, PrimaryGeneratedColumn } from "typeorm";
import { AutoMap } from "@automapper/classes";
@Entity()
export class Product {
@AutoMap()
@PrimaryGeneratedColumn()
productId: number;
@AutoMap()
@Column({ type: 'varchar' })
productName: string
;
@AutoMap()
@Column({ type: 'float' })
price: number;
@AutoMap()
@Column({ type: 'uuid' })
userId: string;
}
and then created an automapper profile like this:
import { Injectable } from "@nestjs/common";
import { AutomapperProfile, InjectMapper } from "@automapper/nestjs";
import { Mapper, createMap, createMapper, forMember, ignore } from "@automapper/core";
import { CreateProductDto } from "./create-product.dto";
import { Product } from "../entities/product.entity";
import { UpdateProductDto } from "./update-product.dto";
@Injectable()
export class ProductMapper extends AutomapperProfile{
constructor(
@((InjectMapper as any)()) mapper: Mapper
){
super(mapper);
}
override get profile(){
return (mapper: Mapper) => {
createMap(mapper, CreateProductDto, Product, forMember(dest => dest.productId, ignore()))
createMap(mapper, UpdateProductDto, Product)
createMap(mapper, Product, CreateProductDto )
createMap(mapper, UpdateProductDto, Product)
createMap(mapper, Product, UpdateProductDto)
}
}
}
and used that in the service and it working just fine,
now I have another DTO for updating like below where I used mapped type from the swagger lib:
import { PartialType } from '@nestjs/mapped-types';
import { CreateProductDto } from './create-product.dto';
export class UpdateProductDto extends PartialType(CreateProductDto) {}
but this one deos not work and it cannot perform the mapping... any thoughts?? thanks.
The problem is that when you use PartialType, it doesn't automatically add the @AutoMap decoration to fields, which you need for AutoMapper. To fix this, make a new file named custom-field-partial-type.ts and copy the code from this link: https://gist.github.com/Copystrike/bfc5010100aba362002616f9eca7fa25
What the code does is simple: it lets you add custom decorators when you use the applyFields function. This means you can add the @AutoMap decorator, which is important for mapping.
Now, you can do things like:
Or you could even go a little more complex and do:
This code only adds the @AutoMap decorator to the "text" field.
I have opened an issue on the @nestjs/graphql repository on GitHub, and maybe someone will be able to integrate this into the actual library. Here is the link to the issue: https://github.com/nestjs/graphql/issues/3201