Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 13 additions & 11 deletions blog/2025-10-signal-forms-part1/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: "Angular Signal Forms Part 1: Getting Started with the Basics"
author: Danny Koppenhagen and Ferdinand Malcher
mail: dannyferdigravatar@fmalcher.de # Gravatar
published: 2025-10-13
lastModified: 2025-10-22
lastModified: 2025-11-09
keywords:
- Angular
- Signals
Expand Down Expand Up @@ -164,7 +164,7 @@ Notice, that we also use the form attribute `novalidate`: It disables the native
We will handle validation later by using a form schema.

```html
<form (submit)="submitForm($event)" novalidate>
<form (submit)="submitForm()" novalidate>
<div>
<label for="username">Username</label>
<input id="username" type="text" [field]="registrationForm.username" />
Expand Down Expand Up @@ -258,7 +258,8 @@ Signal Forms provide two approaches for handling form submission:
Basic synchronous submission and the more powerful `submit()` function for asynchronous operations.

All approaches start with a form submission event handler: In the template, we already used the `(submit)` event binding on the `<form>` element.
It is always necessary to prevent the default form submission behavior by calling `e.preventDefault()` in our `submitForm()` handler method.
It is necessary to prevent the default form submission behavior by synchronously returning `false` from our `submitForm()` handler method.
Otherwise, the page will reload on form submission.

### Basic Synchronous Submission

Expand All @@ -268,12 +269,13 @@ For basic cases where you want to process form data synchronously, you can direc
// ...
export class RegistrationForm {
// ...
protected submitForm(e: Event) {
e.preventDefault();

protected submitForm() {
// Access current form data
const formData = this.registrationModel();
console.log('Form submitted:', formData);

// Prevent reloading (default browser behavior)
return false;
}
}
```
Expand Down Expand Up @@ -316,14 +318,14 @@ export class RegistrationForm {
// ...
readonly #registrationService = inject(RegistrationService);
// ...
protected async submitForm(e: Event) {
e.preventDefault();

await submit(this.registrationForm, async (form) => {
protected submitForm() {
submit(this.registrationForm, async (form) => {
await this.#registrationService.registerUser(form().value());
console.log('Registration successful!');
this.resetForm();
});

return false;
}

protected resetForm() {
Expand All @@ -340,7 +342,7 @@ When submitting the form we can now see that the value of the `submitting()` sig
After the asynchronous operation is complete, it switches back to `false`.

```html
<form (submit)="submitForm($event)">
<form (submit)="submitForm()">
<!-- ... -->

<button
Expand Down
14 changes: 7 additions & 7 deletions blog/2025-10-signal-forms-part2/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: 'Angular Signal Forms Part 2: Advanced Validation and Schema Patterns'
author: Danny Koppenhagen and Ferdinand Malcher
mail: dannyferdigravatar@fmalcher.de # Gravatar
published: 2025-10-15
lastModified: 2025-10-30
lastModified: 2025-11-09
keywords:
- Angular
- Signals
Expand Down Expand Up @@ -451,17 +451,15 @@ While client-side validation catches most errors before submission, server-side
Signal Forms provide an elegant way to handle these errors and display them to users with proper field-level feedback.
When using the `submit()` function, we can return an array of validation errors from the submission callback to assign them to specific fields or to the form itself.

The helper type `WithField` ensures that each error contains a reference to the field it belongs to.
The type `ValidationErrorWithField` ensures that each error contains a reference to the field it belongs to.

```typescript
import { /* ... */, WithField, ValidationErrorWithField } from '@angular/forms/signals';
import { /* ... */, ValidationErrorWithField } from '@angular/forms/signals';

export class RegistrationForm {
// ...
protected async submitForm(e: Event) {
e.preventDefault();

await submit(this.registrationForm, async (form) => {
protected submitForm() {
submit(this.registrationForm, async (form) => {
const errors: ValidationErrorWithField[] = [];

try {
Expand Down Expand Up @@ -490,6 +488,8 @@ export class RegistrationForm {

return errors;
});

return false;
}
}
```
Expand Down
4 changes: 2 additions & 2 deletions blog/2025-10-signal-forms-part3/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: 'Angular Signal Forms Part 3: Child Forms and Custom UI Controls'
author: Danny Koppenhagen and Ferdinand Malcher
mail: dannyferdigravatar@fmalcher.de # Gravatar
published: 2025-10-20
lastModified: 2025-10-20
lastModified: 2025-11-09
keywords:
- Angular
- Signals
Expand Down Expand Up @@ -205,7 +205,7 @@ Finally, we integrate the `IdentityForm` component in our main form template.
To make things work, we pass the `identity` field tree of our main form to the child component via property binding.

```html
<form (submit)="submit($event)">
<form (submit)="submit()">
<!-- ... -->
<app-identity-form [identity]="registrationForm.identity" />
<!-- ... -->
Expand Down