Cos’è RxFormMapper? RxFormMapper è una libreria sviluppata per Angular che permette di convertire, tramite annotazioni, classi in reactive form e viceversa.
Quando usare RxFormMapper?
A volte hai bisogno di trasformare le classi che hai in reactive form. Ad esempio, supponiamo che tu abbia un modello utente che vuoi compilare tramite un modulo:
export class User {
name: string;
surname: string;
age: number;
}
Cosa fare quindi? Come creo un form utente? La soluzione classica è creare manualmente delle istanze di Reactive Form e assegnare ogni proprietà del tuo modello ai vari controller.
new FormGroup(
name: new FormControl(user.name),
surname: new FormControl(user.surname),
age: new FormControl(user.age),
);
Tuttavia, le cose possono complicarsi rapidamente con gerarchie di oggetti più complesse.
Per evitare tutto questo, puoi utilizzare RxFormMapper:
export class User {
@FormControl()
name: string;
@FormControl()
surname: string;
@FormControl()
age: number;
}
Perché usare RxFormMapper? RxFormMapper accelera lo sviluppo dei tuoi form evitando boilerplate ridondante nel codice. I principali vantaggi sono:
- Zero configurazione: tramite annotazioni elimina il boilerplate per creare e assegnare i form.
- Dependency Injection: RxFormMapper sfrutta il container DI di Angular per risolvere i validator e i custom mapper.
- Custom mapper: Se vuoi creare form personalizzati per campi specifici, puoi farlo facilmente con il decoratore
@CustomControl
.
Iniziamo a scrivere codice
Installiamo il pacchetto npm
npm i rx-form-mapper --save
reflect-metadata
è necessario (con Angular+ dovresti già avere questa dipendenza installata).
npm i reflect-metadata --save
Includiamo il modulo
Importiamo RxFormMapperModule nel tuo AppModule
// app.module.ts
import { RxFormMapperModule } from 'rx-form-mapper';
@NgModule({
imports: [RxFormMapperModule.forRoot()],
})
export class AppModule { }
Definiamo il modello
// user-registration.model.ts
export class UserRegistration {
public name: string;
public surname: string;
public birthday: Date;
public email: string;
public password: string;
public passwordCheck: string;
}
Annotiamolo
RxFormMapper ti consente di specificare tramite annotazioni il tipo di AbstractControl per ogni campo nel tuo modello: FormControl, FormGroup e FormArray.
// user-registration.model.ts
import { Validators } from '@angular/forms';
import { FormControl, Form } from 'rx-form-mapper';
import { AlreadySignedAsyncValidator, noWhitespace, passwordCheck } from './app-validators';
@Form({validators: passwordCheck })
export class UserRegistration {
@FormControl({ validators: noWhitespace })
public name: string;
@FormControl({ validators: noWhitespace })
public surname: string;
@FormControl({ validators: Validators.required })
public birthday: Date;
@FormControl({
validators: [Validators.required, Validators.email],
asyncValidators: AlreadySignedAsyncValidator
})
public email: string;
@FormControl({ validators: noWhitespace })
public password: string;
@FormControl({ validators: noWhitespace })
public passwordCheck: string;
}
Puoi trovare ulteriori informazioni sulle annotazioni di RxFormMapper consultando la pagina GitHub indicata all’inizio di questo articolo.
Aspetta… AsyncValidators? Come inietti i servizi?!
Non preoccuparti: RxFormMapper risolve automaticamente tutti i validator registrati all’interno del container Angular per te! 😉
// already-signed-async.validator.ts
@Injectable()
export class AlreadySignedAsyncValidator implements AsyncValidator {
public constructor(private readonly http: HttpClient) {}
validate(control: AbstractControl): Promise<ValidationErrors>|Observable<ValidationErrors> {
if (isWhitespace(control.value)) {
return of(null);
}
return http.get<>('your url').pipe(
map(exists => exists ? ({ alreadySigned: true }) : null)
);
}
}
// app.module.ts
import { RxFormMapperModule } from 'rx-form-mapper';
import { AlreadySignedAsyncValidator } from './validators';
@NgModule({
imports: [RxFormMapperModule.forRoot()],
providers: [AlreadySignedAsyncValidator]
})
export class AppModule { }
Costruiamo il nostro form
// app.component.ts
import { Component } from "@angular/core";
import { FormGroup } from "@angular/forms";
import { RxFormMapper } from "rx-form-mapper";
import { UserRegistration } from "./user-registration";
@Component({
selector: "my-app",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
public readonly form: FormGroup;
public constructor(mapper: RxFormMapper) {
this.form = mapper.writeForm(new UserRegistration());
}
}
Puoi trovare il codice sorgente di questo articolo su stackblitz 😁
Conclusioni
RxFormMapper è uno strumento fantastico che ti consente di creare reactive form in modo semplice e dichiarativo tramite le annotazioni, permettendoti di concentrarti sulle tue funzionalità. Questo tipo di framework è particolarmente adatto per applicazioni basate su CRUD, poiché riduce drasticamente il codice da mantenere.
Se questa guida ti è stata utile, non dimenticare di condividerla con chiunque potrebbe trarne beneficio 😃
So long, and thanks for all the fish 🐬