From 291c596305695154f1408c3a4593ad05aef90345 Mon Sep 17 00:00:00 2001 From: Tsironis Ioannis Date: Mon, 9 Mar 2026 15:14:44 +0200 Subject: [PATCH 1/2] feat: fix forms simplest signal form challenge --- .../src/app/app.component.html | 102 ++++++++++ .../src/app/app.component.ts | 187 ++++-------------- 2 files changed, 144 insertions(+), 145 deletions(-) create mode 100644 apps/forms/61-simplest-signal-form/src/app/app.component.html diff --git a/apps/forms/61-simplest-signal-form/src/app/app.component.html b/apps/forms/61-simplest-signal-form/src/app/app.component.html new file mode 100644 index 000000000..748d4e96e --- /dev/null +++ b/apps/forms/61-simplest-signal-form/src/app/app.component.html @@ -0,0 +1,102 @@ +
+
+

Simple Form

+ +
+
+ + + @if (userForm.name().errors().length > 0 && userForm.name().touched()) { + @for (error of userForm.name().errors(); track error) { +

{{ error.message }}

+ } + } +
+ +
+ + +
+ +
+ + + @if (userForm.age().errors().length > 0 && userForm.age().touched()) { + @for (error of userForm.age().errors(); track error) { +

{{ error.message }}

+ } + } +
+ +
+ + +
+ +
+ + +
+
+ + @if (submittedData()) { +
+

+ Submitted Data: +

+
{{ submittedData() | json }}
+
+ } +
+
diff --git a/apps/forms/61-simplest-signal-form/src/app/app.component.ts b/apps/forms/61-simplest-signal-form/src/app/app.component.ts index 48edfb268..3970d91bd 100644 --- a/apps/forms/61-simplest-signal-form/src/app/app.component.ts +++ b/apps/forms/61-simplest-signal-form/src/app/app.component.ts @@ -1,160 +1,57 @@ import { JsonPipe } from '@angular/common'; -import { Component, signal, WritableSignal } from '@angular/core'; import { - FormControl, - FormGroup, - ReactiveFormsModule, - Validators, -} from '@angular/forms'; + ChangeDetectionStrategy, + Component, + signal, + WritableSignal, +} from '@angular/core'; +import { form, FormField, max, min, required } from '@angular/forms/signals'; + +type UserData = { + name: string; + lastname: string; + age: number; + note: string; +}; @Component({ selector: 'app-root', - imports: [ReactiveFormsModule, JsonPipe], - template: ` -
-
-

Simple Form

- -
-
- - - @if (form.controls.name.invalid && !form.controls.name.untouched) { -

Name is required

- } -
- -
- - -
- -
- - - @if (form.controls.age.invalid && !form.controls.age.untouched) { -

- @if (form.controls.age.hasError('min')) { - Age must be at least 1 - } - @if (form.controls.age.hasError('max')) { - Age must be at most 99 - } -

- } -
- -
- - -
- -
- - -
-
- - @if (submittedData()) { -
-

- Submitted Data: -

-
{{ submittedData() | json }}
-
- } -
-
- `, + imports: [JsonPipe, FormField], + templateUrl: './app.component.html', + changeDetection: ChangeDetectionStrategy.OnPush, }) export class AppComponent { - form = new FormGroup({ - name: new FormControl('', { - validators: Validators.required, - nonNullable: true, - }), - lastname: new FormControl('', { nonNullable: true }), - age: new FormControl(null, [ - Validators.min(1), - Validators.max(99), - ]), - note: new FormControl('', { nonNullable: true }), + private readonly _initialData: UserData = { + name: '', + lastname: '', + age: NaN, + note: '', + }; + private _userModel = signal(this._initialData); + + protected userForm = form(this._userModel, (schemaPath) => { + required(schemaPath.name, { message: 'Name is required' }); + min(schemaPath.age, 1, { message: 'Age must be at least 1' }); + max(schemaPath.age, 99, { message: 'Age must be at most 99' }); }); + protected submittedData: WritableSignal = signal(null); - submittedData: WritableSignal<{ - name: string; - lastname: string; - age: number | null; - note: string; - } | null> = signal(null); + public onSubmit(event: Event): void { + event.preventDefault(); - onSubmit(): void { - if (this.form.valid) { - this.submittedData.set(this.form.getRawValue()); - console.log('Form submitted:', this.submittedData); + if (this.userForm().valid()) { + this.setSubmittedData(); } } - onReset(): void { - this.form.reset(); - this.submittedData.set(null); + public onReset(): void { + this.userForm().reset(this._initialData); + this.setSubmittedData(); + } + + private setSubmittedData(): void { + const formData = this._userModel(); + console.log('Form submitted:', formData); + this.submittedData.set(formData); } } From 3d62432edbdfd13c9420e2759b73ccaf41c45043 Mon Sep 17 00:00:00 2001 From: Tsironis Ioannis Date: Tue, 10 Mar 2026 11:18:03 +0200 Subject: [PATCH 2/2] feat: use declarative code to submit the form --- .../src/app/app.component.html | 3 +- .../src/app/app.component.ts | 45 ++++++++++++------- 2 files changed, 29 insertions(+), 19 deletions(-) diff --git a/apps/forms/61-simplest-signal-form/src/app/app.component.html b/apps/forms/61-simplest-signal-form/src/app/app.component.html index 748d4e96e..459385632 100644 --- a/apps/forms/61-simplest-signal-form/src/app/app.component.html +++ b/apps/forms/61-simplest-signal-form/src/app/app.component.html @@ -2,7 +2,7 @@

Simple Form

-
+