I'm trying to inject a service in a pipe. I'm using pipe (signupPipe) in a controller, POST method.
// signup.pipe.ts
import { PipeTransform, Injectable, BadRequestException } from '@nestjs/common';
import * as bcrypt from 'bcrypt';
import { UserService } from './user.service'
@Injectable()
export class SignupPipe implements PipeTransform<any> {
constructor(private userService: UserService) { }
async transform(value: any) {
// validate password
const areTheSame = this.validatePassword(value.password, value.passwordRepeat);
if (!areTheSame) {
throw new BadRequestException("Password are not the same.");
}
// check if account exists
const isExists = await this.userService.findOne(value.email)
if (isExists) {
throw new BadRequestException("Account with provided email already exists.");
}
// create encrypted password
const signupData = {...value}
signupData.password = await bcrypt.hash(value.password, 10)
return signupData
}
private validatePassword(password: string, passwordRepeat: string): boolean {
return password === passwordRepeat
}
}
My controller:
@Controller("user")
export class UserController {
constructor(private userService: UserService, private signupPipe: SignupPipe) { }
@Post("signup")
async signup(@Body(this.signupPipe) createUserDto: CreateUserDto) {
return await this.userService.signup(createUserDto)
}
}
User module:
@Module({
imports: [MongooseModule.forFeature([{ name: User.name, schema: UserSchema }])],
controllers: [UserController],
providers: [
UserService
],
exports: [UserService]
})
export class UserModule { }
How to correctly inject a pipe which includes another service injected by DI? Now it doesn't work, error:
Nest can't resolve dependencies of the UserController (UserService, ?). Please make sure that the argument SignupPipe at index [1] is available in the UserModule context.
Does my pipe is correct? I'm not sure, because it does a few things (validate pwd/repeat, check if acc exists, encrypt pwd) - so probably it breaks SOLID rule (SRP) - so should I split these 3 roles into 3 separated pipes?
Thanks.
You can't use class members inside of decorators, it's a language constraint of typescript. However, you can allow Nest to do the DI work for you by using @Body(SignupPipe)
on it's own. Nest will read the constructor of the pipe and see what needs to be injected into it.
@Controller("user")
export class UserController {
constructor(private userService: UserService, ) { }
@Post("signup")
async signup(@Body(SignupPipe) createUserDto: CreateUserDto) {
return await this.userService.signup(createUserDto)
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With