Forms

Forms are a great way to organise and validate the input from the user. Forms are simple classes inside the Forms directory that extend the Form class and uses the @Field decorator:

import { Field, Form } from '@Typetron/Forms'

export class LoginForm extends Form {

    @Field()
    email: string

    @Field()
    password: string
}

You can use forms in your controller methods by just type-hinting them, like in the example below:

import { Controller, Get, Post } from '@Typetron/Router'
import { LoginForm } from 'App/Forms/LoginForm'

@Controller()
export class AuthController {

    @Post('login')
    login(loginForm: LoginForm) {
        return ['A nice object with the data for the login form', loginForm]
    }
}

Of course, for security reasons, you might want to validate the input of your forms. You can do this by using the @Rules decorator where you can add a list of rules that will check the form’s fields:

import { Field, Form, Rules } from '@Typetron/Forms'
import { Required, MinLength } from '@Typetron/Validation/Rules'

export class LoginForm extends Form {

    @Field()
    @Rules(Required)
    email: string

    @Field()
    @Rules(
        Required,
        MinLength(6)
    )
    password: string
}

In the form above we’ve set the email and password fields to be required, with the password having at least 6 characters in length. If the form is not valid, Typetron will throw an HTTP error with the code 422 UNPROCESSABLE_ENTITY.

Custom validation

To create a custom validation rule, all you have to do is to extend the base Rule class from the Validation module, like in the example below:

import { Rule, RuleValue } from '@Typetron/Validation'

export class IsNumber extends Rule {
    identifier = 'isNumber'

    passes(attribute: string, value: RuleValue): boolean {
        return !isNaN(Number(value))
    }

    message(attribute: string): string {
        return `The ${attribute} is not a number`
    }
}

To create a validation rule that accepts parameters, you will have to wrap the class in a function like so:

import { Rule, RuleInterface, RuleValue } from '@Typetron/Validation'
import { Type } from '@Typetron/Support'

export function InArray(values: string[]): Type<RuleInterface> {
    return class extends Rule {
        identifier = 'inArray'

        passes(attribute: string, value: RuleValue): boolean {
            return values.includes(value as string)
        }

        message(attribute: string): string {
            return `The ${attribute} must have a value from the following list ${values.join(', ')}`
        }
    }
}