How use profiles from nartc/automapper into a nestjs application

妖精的绣舞 提交于 2020-06-16 17:15:08

问题


I'm trying to use AutoMapper for nodejs from nartc/automapper lib inside a NestJS project, but I'm having troubles when trying to use Profiles functionality. Here is my configuration:

App.module

@Module({
  imports: [
    AutomapperModule.withMapper(),
  ],
  controllers: [],
  providers: [],
})
export class AppModule implements NestModule {}

Profile

@Profile()
export class RoleProfile extends ProfileBase {
  constructor(@InjectMapper() mapper: AutoMapper) {
    super();

    mapper
      .createMap(Role, RoleWithPermissionDto)
      .forMember(
        dest => dest.id,
        mapFrom(src => src.id),
      )
      .forMember(
        dest => dest.name,
        mapFrom(src => src.name),
      )
      .forMember(
        dest => dest.created,
        mapFrom(src => src.createAt),
      )
      .forMember(dest => dest.permissions, ignore());
  }
}

Controller

@Controller('roles')
export class RolesController {
  constructor(private readonly rolesService: RolesService, @InjectMapper() private readonly mapper: AutoMapper) {}

  @Get()
  public async getRoles(@CurrentUser() user: CurrentUserDto) {
    const roles: Role[] = await this.rolesService.findByCompanyId(user.companyId);
    return this.mapper.mapArray(roles, RoleWithPermissionDto);
  }
}

When I call my controller action (getRoles), I get this error message on console:

Mapping not found for source class Role extends base_entity_1.BaseEntity {
} and destination class RoleWithPermissionDto {
    static _OPENAPI_METADATA_FACTORY() {
        return { id: { required: false, type: () => Number }, name: { required: true, type: () => String }, permissions: { required: true, type: () => [require("../permissions/permission.dto").PermissionDto] }, createdAt: { required: true, 
type: () => Date }, created: { required: true, type: () => Date } };
    }
} +5034ms
Error: Mapping not found for source class Role extends base_entity_1.BaseEntity {
} and destination class RoleWithPermissionDto {
    static _OPENAPI_METADATA_FACTORY() {
        return { id: { required: false, type: () => Number }, name: { required: true, type: () => String }, permissions: { required: true, type: () => [require("../permissions/permission.dto").PermissionDto] }, createdAt: { required: true, 
type: () => Date }, created: { required: true, type: () => Date } };
    }
}
    at getMappingForDestination (D:\trabajo\cencogan\project-mercury-api\node_modules\@nartc\automapper\dist\automapper.cjs.development.js:131:11)
    at AutoMapper.mapArray$1 [as mapArray] (D:\trabajo\cencogan\project-mercury-api\node_modules\@nartc\automapper\dist\automapper.cjs.development.js:1262:19)
    at RolesController.getRoles (D:\trabajo\cencogan\project-mercury-api\dist\src\roles\roles.controller.js:35:28)
    at process._tickCallback (internal/process/next_tick.js:68:7)

If I decide to create the mapping directly inside the controller, everything work as expected. for example:

@Controller('roles')
export class RolesController {
  constructor(private readonly rolesService: RolesService, @InjectMapper() private readonly mapper: AutoMapper) {}

  @Get()
  public async getRoles(@CurrentUser() user: CurrentUserDto) {
    const roles: Role[] = await this.rolesService.findByCompanyId(user.companyId);
    this. mapper
      .createMap(Role, RoleWithPermissionDto)
      .forMember(
        dest => dest.id,
        mapFrom(src => src.id),
      )
      .forMember(
        dest => dest.name,
        mapFrom(src => src.name),
      )
      .forMember(
        dest => dest.created,
        mapFrom(src => src.createAt),
      )
      .forMember(dest => dest.permissions, ignore());
    return this.mapper.mapArray(roles, RoleWithPermissionDto);
  }
}

I supposed my Profile is not getting invoked, have anybody used this library in a NestJS project ?

I use feature modules, so my controller is registered inside RolesModule.

I will be grateful for any help


回答1:


I am the author of @nartc/automapper and nestjsx-automapper and it appears as you're using the nestjsx-automapper already.

I don't see anything wrong with your setup. However, due to TypeScript limitation, if you have the Profile (in this case, RoleProfile) in a separate file, then you have to import the RoleProfile in some other file that WILL be guaranteed to execute (the Module is the best place)

import './role.profile';

@Module(...)
export class RoleModule {}

If you want to separate Profile out to a separate file, then you need to make sure that file gets executed by importing it somewhere (again, the module is a good place).

I did mention this piece in the README but it seems to be not highlighted enough to grab people's attention.

Another thing is in your Profile constructor, you don't need @InjectMapper since mapper will be passed in for you when nestjsx-automapper runs mapper.addProfile() internally.

Sorry for any inconvenience.



来源:https://stackoverflow.com/questions/61429313/how-use-profiles-from-nartc-automapper-into-a-nestjs-application

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!