Description...
- Add package to project.
Add validation package to dependencies
in package.json
"dependencies": {
...
"validation": "git+https://gitlab.com/itdotfocus/itfformbuilder/itfformbuilder.git",
...
},
and install new package
yarn install
- Add package to project.
Add validation package to dependencies
in package.json
"dependencies": {
...
"validation": "git+https://gitlab.com/itdotfocus/itfformbuilder/itfformbuilder.git",
...
},
and install new package
yarn install
- Add global pipe
Create ValidationPipe.ts
in folder ./pipes/
import { PipeTransform, Injectable, ArgumentMetadata, BadRequestException, Type } from '@nestjs/common';
import { Validation } from 'validation';
@Injectable()
export class ValidationPipe implements PipeTransform<any> {
transform = async (value: any, { metatype }: ArgumentMetadata) => {
if (!metatype || !this.toValidate(metatype)) {
return value;
}
return await this.valid(value, metatype);
}
private toValidate = (metatype: Function): boolean => { // tslint:disable-line
const types: Function[] = [String, Boolean, Number, Array, Object]; // tslint:disable-line
return !types.includes(metatype);
}
private valid = async (value: any, metatype: Type<any>) => {
const schema = Validation.getSchema(metatype);
if (!schema) {
return value;
}
return await schema.validate(value, { stripUnknown: true, abortEarly: false })
.catch(err => {
throw new BadRequestException(err.inner.map(this.filterMessages));
})
}
filterMessages = ({ path, message}) => ({ path, message });
}
Use it globally by adding to main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { ValidationPipe } from '../pipes/validation.pipe';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalPipes(new ValidationPipe());
await app.listen(3001);
}
bootstrap();
Note the correct import becaus nest.js
has the same pipe.
import { ValidationPipe } from '../pipes/validation.pipe';
- Add form error functions to utils folder.
import { ApiErrorCode } from 'types';
import { BadRequestException, HttpStatus } from '@nestjs/common';
export const formError = (path: string, message: ApiErrorCode) => {
throw new BadRequestException({ code: HttpStatus.BAD_REQUEST, message: [{ path, message }] });
}
export const formErrors = (message: { path: string, message: ApiErrorCode }[]) => {
throw new BadRequestException({ code: HttpStatus.BAD_REQUEST, message });
}
Create file with form validators
First step is create validation class with @Form()
decorator.
The post
property of the argument is required. It defines path to send form (if we add edit mode then a parameter containing id will be added to this path for edit form).
The edit
property defines path to get edit form details (parameter containing id will be added to this path by FrontEnd) and active edit mode.
@Form({ edit: '/offer/details', post: '/offer/add' })
export class OfferDto {}
Next step is add constructor with private argument formName
with the default value witch is unique name of form (the best is class name);
constructor(private formName = 'OfferDto') {}
Last is add properties to validation class with for least one decorator.
Finally we have complete form to add and update data.
@Form({ edit: '/offer/details', post: '/offer/add' })
export class OfferDto {
constructor(private formName = 'OfferDto') {}
@IsDate()
fromAt: Date;
@IsDate()
toAt: Date;
@IsEnum(OfferCategory)
category: OfferCategory;
@IsEnum(OfferWages)
wages: OfferWages;
}
Remember about export all form/validators like interfaces.
One you have to do is add EP but there are a few things things you need to remember.
- Always use Post method (add or update). You can use two EP (add and update) but both with
@Post()
. - Type your body (or params or query) by validator from
types
package.
@Post('/add/:offerId?')
async addOrUpdateOffer(
@Me() user: User,
@Body() offerDto: OfferDto,
@Param('offerId') offerId: string,
): Promise<null> {
return this.offerService...;
}
In Body of EP function is validated and transformated dto object.
For throwing error user BadRequestException
with ApiErrorCode
.
throw new BadRequestException(ApiErrorCode.InvalidParams);
This Error will be displayed in toast.
For throwing field error use formError
function form utils.
formError('email', ApiErrorCode.EmailInUse);
First argument is name of field, next is ApiErrorCode.
This Error will be displayed under input.
For throwing field error use formErrors
function form utils.
formError([{ path: 'email', message: ApiErrorCode.EmailInUse }, ...]);
This Errors will be displayed under inputs.
Define string
type of property.
@IsString()
Property can't be undefined
, null
or ''
@IsRequired()
Define min length of string
.
@MinLength(value: number)
Define max length of string
.
@MaxLength(value: number)
Define property as email string;
@Email()
Define property as pwd string;
@Pwd(minLength?: number)
Default min length is 8
Define property as repeated password string;
@Pwd2(pwdFieldName?: string)
Default password field name is pwd
Define number
type of property.
@IsNumber()
Define min value of property.
@Min(value: number)
Define max value of property.
@Max(value: number)
Define boolean
type of property.
@IsBoolean()
Define date
type of property.
@IsDate()
Define min date.
@MIn(date: Date)
Define max date.
@Max(date: DAte)
Define array
type of property.
@IsArray(validationClass: any)
Define min array
length.
@Min(length: number)
Define max array
length.
@Max(length: number)
Value have to be defined enum.
@IsEnum<T>(myEnum: T)
;