问题
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