Angular 11+ new way form validation with RxWeb
Tags: angular, rxjs, webdev, typescript
Published: 2021-11-10 20:40:32

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ech8f87wqpisei62jrdh.png)

## RxWeb คืออะไร

An Open-Source Architecture
for Web Applications in Angular & Vue & .Net Core
DOMAIN-DRIVEN DESIGN | SERVERLESS | MICROSERVICES | RESTFUL

## Goal

Provides all type of clientside validations.
Easy way to create Angular Reactive Form Group & Template Driven Form Validation with less lines of code & clean code.
Easy to create Dynamic Reactive Form / Template Driven Form.

## การ Validate forms ปกติใน Angular
```typescript
/** app.module.ts */

import { FormsModule, ReactiveFormsModule } from '@angular/forms';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    FormsModule,
    ReactiveFormsModule,
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

```

```typescript
/** app.component.ts */

import { FormBuilder, FormGroup } from '@angular/forms';

export class AppComponent implements OnInit {
  myForm!: FormGroup;
  constructor(private formBuilder: FormBuilder) { }
  ...

  ngOnInit(): void {
    this.myForm = this.formBuilder.group({
      name: [null, [Validators.required]],
      lastName: [null, [Validators.required]],
      age: [null, [Validators.required]]
    })
  }
}
```
โค้ดมารวมกันที่อยู่ component อาจจะทำให้ไม่ clean code และ less code ได้

```html
<!-- app.component.html -->

  <form [formGroup]="myForm">
    Name: <input type="text" formControlName="name">
    <label>{{myForm.get('name').errors}}</label>

    LastName: <input type="text" formControlName="lastName">
    <label>{{myForm.get('lastName').errors}}</label>
    
    Ager: <input type="text" formControlName="age">
    <label>{{myForm.get('age').errors}}</label>
  </form>


```

## มาดูการ Validate form แบบใหม่ ด้วย RxWeb
`$ npm install @rxweb/reactive-form-validators`

```typescript
/** app.module.ts */

import { RxReactiveFormsModule } from '@rxweb/reactive-form-validators';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    FormsModule,
    RxReactiveFormsModule,
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

```

## สร้าง models เพื่อใช้การทำ validate forms
```typescript
/** models/user.model.ts*/

import { minLength, required } from "@rxweb/reactive-form-validators";

export class UserModel {
  @required()
  @minLength({ value: 5 })
  userName: string;

  @required()
  lastName: string;

  @required()
  age: number;

  ...
}

```
แยกโค้ดให้ไป validate โดยการใช้ models ทำให้ code clean  & less code มากขึ้น filling look like Java, Nestjs โดยการใช้ class validator decorator มาใช้แทนที่จะเขียน รวมอยู่ใน component เดียวกัน

## เริ่มผูก models เข้ากับ formGroup
```typescript
/** app.component.ts */

import { FormGroup } from '@angular/forms';
import { RxFormBuilder } from '@rxweb/reactive-form-validators';
import { UserModel } from './models/user.model';

export class AppComponent implements OnInit {
  myForm!: FormGroup;
  constructor(private formBuilder: RxFormBuilder) { }
  ...

  ngOnInit(): void {
    let user = new UserModel();
    this.userForm = this.formBuilder.formGroup(user);
  }
}
```
ดูจาก function ngOnInit() ทำให้ดู clean code & less code มาก

## Config validationMessage
```typescript
/** app.component.ts */
import { ReactiveFormConfig } from '@rxweb/reactive-form-validators';
...

export class AppComponent implements OnInit {
  myForm!: FormGroup;
  constructor(private formBuilder: RxFormBuilder) { }
  ...

  ngOnInit(): void {

      ReactiveFormConfig.set({
      validationMessage: {
        required: "This field is required",
        minLength: "minimum length is {{1}}",
      }
    });

    let user = new UserModel();
    this.userForm = this.formBuilder.formGroup(user);
  }
}
```
เราสามารถ custom error message มาเพื่อแสดง error message หรือจะเขียนแยกไว้แล้วค่อยมาใช้งานก็ได้

## แสดง errorMessage ที่ html template
```html
<!-- app.component.html -->

<form [formGroup]="myForm">
    Name: <input type="text" formControlName="name">
    <label> {{ userForm?.controls?.name["errorMessage"]}}</label>

    LastName: <input type="text" formControlName="lastName">
    <label>{{ userForm?.controls?.lastName["errorMessage"]}}</label>
    
    Ager: <input type="text" formControlName="age">
    <label>{{ userForm?.controls?.age["errorMessage"]}}</label>
</form>

```

## Benefit
เราสามารถทำ Group หรือทำ Array Group เพื่อให้ Validate forms แบบ complex รวมไปถึงการ reused ในต่าง component ได้แบบสบายๆ

#### ศึกษาข้อมูลเพิ่มได้ที่ 
<a href="https://docs.rxweb.io/getting-started">https://docs.rxweb.io/getting-start</a>

## การ validate แบบเดียวกัน Backend

#### NestJs class validators
<a href="https://www.npmjs.com/package/class-validator">https://www.npmjs.com/package/class-validator</a>

#### Java Bean validations
<a href="https://docs.oracle.com/javaee/7/tutorial/bean-validation001.htm">https://docs.oracle.com/javaee/7/tutorial/bean-validation001.htm</a>