🧩 Exercícios: Reactive Forms, FormBuilder e Validações Customizadas
Spec Frontend Com Angular • Trilha Progressiva em 4 Níveis
🎯 Nível 1: Fundamentos
Problema 13.1 — Formulário Reativo com FormBuilder e FormControl
Contexto: Formulário Reativo com FormBuilder e FormControl no contexto de Reactive Forms, FormBuilder e Validações Customizadas.
Requisitos de Execução:
- Criar formulário de login com
FormBuilder.group({ email: ['', [Validators.required, Validators.email]] }).
Resultado Esperado
Formulário reativo com validações síncronas integradas.
📤 Instruções de Entrega (Microsoft Teams)
- Salve o arquivo como:
Atividade_13_1_SeuNome - Envie na tarefa:
Atividade Cap 13 - Reactive Forms, FormBuilder e Validações Customizadas
🔑 Gabarito de Código & Solução Comentada
// login-form.component.ts
import { Component, inject } from '@angular/core';
import { ReactiveFormsModule, FormBuilder, Validators } from '@angular/forms';
@Component({
selector: 'app-login-form',
standalone: true,
imports: [ReactiveFormsModule],
template: `
<form [formGroup]="form" (ngSubmit)="onSubmit()">
<input formControlName="email" placeholder="E-mail" />
<button type="submit" [disabled]="form.invalid">Entrar</button>
</form>
`
})
export class LoginFormComponent {
private fb = inject(FormBuilder);
form = this.fb.group({
email: ['', [Validators.required, Validators.email]],
senha: ['', [Validators.required, Validators.minLength(6)]]
});
onSubmit() { console.log('Dados:', this.form.value); }
}
🔍 Nível 2: Prática
Problema 13.2 — Validador Customizado Síncrono (ValidatorFn)
Contexto: Validador Customizado Síncrono (ValidatorFn) no contexto de Reactive Forms, FormBuilder e Validações Customizadas.
Requisitos de Execução:
- Criar validador
validarDominioEmpresa('empresa.com')que rejeite emails de domínios públicos.
Resultado Esperado
Validador de domínio corporativo aplicado ao campo de e-mail.
📤 Instruções de Entrega (Microsoft Teams)
- Salve o arquivo como:
Atividade_13_2_SeuNome - Envie na tarefa:
Atividade Cap 13 - Reactive Forms, FormBuilder e Validações Customizadas
🔑 Gabarito de Código & Solução Comentada
// validators.ts
import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';
export function validarDominioEmpresa(dominioEsperado: string): ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => {
const email = control.value as string;
if (!email) return null;
return email.endsWith(`@${dominioEsperado}`) ? null : { dominioInvalido: true };
};
}
⚡ Nível 3: Integração
Problema 13.3 — Campos Dinâmicos com FormArray
Contexto: Campos Dinâmicos com FormArray no contexto de Reactive Forms, FormBuilder e Validações Customizadas.
Requisitos de Execução:
- Implementar formulário com lista dinâmica de telefones permitindo adicionar e remover campos com
FormArray.
Resultado Esperado
Campos de formulário adicionados e removidos dinamicamente no FormArray.
📤 Instruções de Entrega (Microsoft Teams)
- Salve o arquivo como:
Atividade_13_3_SeuNome - Envie na tarefa:
Atividade Cap 13 - Reactive Forms, FormBuilder e Validações Customizadas
🔑 Gabarito de Código & Solução Comentada
// dynamic-form.component.ts
import { Component, inject } from '@angular/core';
import { ReactiveFormsModule, FormBuilder, FormArray } from '@angular/forms';
@Component({
selector: 'app-dynamic-form',
standalone: true,
imports: [ReactiveFormsModule],
template: `
<form [formGroup]="form">
<div formArrayName="telefones">
@for (ctrl of telefones.controls; track $index) {
<input [formControlName]="$index" />
}
</div>
<button type="button" (click)="adicionarTelefone()">+ Telefone</button>
</form>
`
})
export class DynamicFormComponent {
private fb = inject(FormBuilder);
form = this.fb.group({ telefones: this.fb.array([this.fb.control('')]) });
get telefones() { return this.form.get('telefones') as FormArray; }
adicionarTelefone() { this.telefones.push(this.fb.control('')); }
}
🏆 Nível 4: Desafio Corporativo
Problema 13.4 — Validação Assíncrona com AsyncValidatorFn e Debounce
Contexto: Validação Assíncrona com AsyncValidatorFn e Debounce no contexto de Reactive Forms, FormBuilder e Validações Customizadas.
Requisitos de Execução:
- Criar validador assíncrono consultando API para verificar se o nome de usuário já está cadastrado.
Resultado Esperado
Validação assíncrona executada com debounce evitando sobrecarga no servidor.
📤 Instruções de Entrega (Microsoft Teams)
- Salve o arquivo como:
Atividade_13_4_SeuNome - Envie na tarefa:
Atividade Cap 13 - Reactive Forms, FormBuilder e Validações Customizadas
🔑 Gabarito de Código & Solução Comentada
// async-validator.ts
import { AbstractControl, AsyncValidatorFn } from '@angular/forms';
import { timer, of } from 'rxjs';
import { switchMap, map } from 'rxjs/operators';
export function checarUsuarioDisponivel(): AsyncValidatorFn {
return (control: AbstractControl) => {
return timer(400).pipe(
switchMap(() => control.value === 'admin' ? of({ usuarioJaExiste: true }) : of(null))
);
};
}