1. Introduction to Angular Form Submission
Form submission means collecting user input from a form and then using that data. In real apps, submitted form data may log in a user, add a student, update a profile, or send a contact message.
User fills form
↓
User clicks Submit
↓
Angular receives ngSubmit
↓
Component validates data
↓
Component sends data to service/API
↓
Show success or error
Checkpoint: Verify before continuing
Complete all checks to continue.
2. Level 0 Meaning
An Angular form is not just HTML. Angular can track values, validity, touched state, dirty state, errors, and submission.
<form (ngSubmit)="submitForm()">
<input name="studentName">
<button type="submit">Submit</button>
</form>
Checkpoint
Complete all checks to continue.
3. Why Form Submission Matters
Login pages, registration pages, admin panels, dashboards, feedback pages, search filters, and payment flows all depend on forms.
| Use Case | Form Fields | Submit Result |
|---|---|---|
| Login | Email, password | Authenticate user |
| Student registration | Name, email, course | Create student record |
| Contact form | Name, email, message | Send message to owner |
| Profile update | Name, phone, address | Update existing user |
Checkpoint
Complete all checks to continue.
4. Two Angular Form Approaches
Angular provides two main approaches to forms: template-driven forms and reactive forms. Both track values and validation, but they organize the code differently.
| Approach | Import | Best For | Mental Model |
|---|---|---|---|
| Template-driven form | FormsModule |
Simple forms | HTML-first |
| Reactive form | ReactiveFormsModule |
Complex forms, validation, dynamic fields, testing | TypeScript-first |
Checkpoint
Complete all checks to continue.
5. Setup a Practice Component
Command
ng generate component pages/form-submission-demo
Add Route
import { Routes } from '@angular/router';
import { FormSubmissionDemo } from './pages/form-submission-demo/form-submission-demo';
export const routes: Routes = [
{ path: 'form-submission', component: FormSubmissionDemo }
];
Run
ng serve
Open:
http://localhost:4200/form-submission
Checkpoint
Complete all checks to continue.
6. Template-driven Form Submission
A template-driven form is easy to start. The form structure is mostly in HTML, and Angular creates the
form model through directives like ngModel.
form-submission-demo.ts
import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
@Component({
selector: 'app-form-submission-demo',
imports: [FormsModule],
templateUrl: './form-submission-demo.html',
styleUrl: './form-submission-demo.css'
})
export class FormSubmissionDemo {
student = { name: '', email: '', course: 'Angular' };
submittedData: unknown = null;
submitTemplateForm(): void {
this.submittedData = { ...this.student };
console.log('Template-driven form submitted:', this.submittedData);
}
}
form-submission-demo.html
<h2>Template-driven Form</h2>
<form #studentForm="ngForm" (ngSubmit)="submitTemplateForm()">
<label>Name
<input name="name" [(ngModel)]="student.name" required minlength="3">
</label>
<label>Email
<input name="email" type="email" [(ngModel)]="student.email" required>
</label>
<label>Course
<select name="course" [(ngModel)]="student.course">
<option value="Angular">Angular</option>
<option value="TypeScript">TypeScript</option>
<option value="JavaScript">JavaScript</option>
</select>
</label>
<button type="submit" [disabled]="studentForm.invalid">Submit</button>
</form>
@if (submittedData) {
<pre>{{ submittedData | json }}</pre>
}
Checkpoint
Complete all checks to continue.
7. Reactive Form Submission
Reactive forms define the form model in TypeScript. This makes validation, testing, dynamic controls, and complex submit logic easier to manage.
form-submission-demo.ts
import { Component } from '@angular/core';
import { ReactiveFormsModule, FormControl, FormGroup, Validators } from '@angular/forms';
@Component({
selector: 'app-form-submission-demo',
imports: [ReactiveFormsModule],
templateUrl: './form-submission-demo.html',
styleUrl: './form-submission-demo.css'
})
export class FormSubmissionDemo {
registrationForm = new FormGroup({
name: new FormControl('', { nonNullable: true, validators: [Validators.required, Validators.minLength(3)] }),
email: new FormControl('', { nonNullable: true, validators: [Validators.required, Validators.email] }),
course: new FormControl('Angular', { nonNullable: true, validators: [Validators.required] })
});
submittedData: unknown = null;
submitReactiveForm(): void {
if (this.registrationForm.invalid) {
this.registrationForm.markAllAsTouched();
return;
}
this.submittedData = this.registrationForm.getRawValue();
console.log('Reactive form submitted:', this.submittedData);
}
}
form-submission-demo.html
<h2>Reactive Form</h2>
<form [formGroup]="registrationForm" (ngSubmit)="submitReactiveForm()">
<label>Name <input formControlName="name"></label>
@if (registrationForm.controls.name.invalid && registrationForm.controls.name.touched) {
<p class="error">Name is required and must have at least 3 characters.</p>
}
<label>Email <input type="email" formControlName="email"></label>
@if (registrationForm.controls.email.invalid && registrationForm.controls.email.touched) {
<p class="error">Enter a valid email.</p>
}
<label>Course
<select formControlName="course">
<option value="Angular">Angular</option>
<option value="TypeScript">TypeScript</option>
</select>
</label>
<button type="submit" [disabled]="registrationForm.invalid">Submit Reactive Form</button>
</form>
Checkpoint
Complete all checks to continue.
8. Validation Before Submit
Validation checks whether the entered data is acceptable. Good forms should not submit invalid data.
| Validator | Meaning | Example |
|---|---|---|
Validators.required |
Field cannot be empty | Name, email, password |
Validators.email |
Must look like an email | student@example.com |
Validators.minLength(3) |
Minimum number of characters | Name should not be too short |
Validators.pattern(...) |
Must match a pattern | Phone, username |
submitReactiveForm(): void {
if (this.registrationForm.invalid) {
this.registrationForm.markAllAsTouched();
return;
}
const formValue = this.registrationForm.getRawValue();
console.log(formValue);
}
Checkpoint
Complete all checks to continue.
9. Important Form States
Angular tracks useful states for each control and form. These states help decide when to show errors.
| State | Meaning | Use |
|---|---|---|
valid |
All validations passed | Enable submit |
invalid |
At least one validation failed | Disable submit or show errors |
touched |
User focused and left the field | Show error after interaction |
dirty |
User changed the value | Warn about unsaved changes |
pending |
Async validation is running | Show checking status |
Checkpoint
Complete all checks to continue.
10. Submit Form Data to an API
In a real app, the component should call a service, and the service should handle the HTTP request.
Provide HTTP Client
import { ApplicationConfig } from '@angular/core';
import { provideHttpClient } from '@angular/common/http';
export const appConfig: ApplicationConfig = {
providers: [provideHttpClient()]
};
student.service.ts
import { Injectable, inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
export interface StudentRegistration {
name: string;
email: string;
course: string;
}
@Injectable({ providedIn: 'root' })
export class StudentService {
private http = inject(HttpClient);
private apiUrl = 'https://example.com/api/students';
registerStudent(data: StudentRegistration): Observable<StudentRegistration> {
return this.http.post<StudentRegistration>(this.apiUrl, data);
}
}
Checkpoint
Complete all checks to continue.
11. Loading, Success, and Error States
A production form should show what is happening. The user should know when the form is submitting, when it succeeded, and when it failed.
isSubmitting = false;
successMessage = '';
errorMessage = '';
submitReactiveForm(): void {
if (this.registrationForm.invalid) {
this.registrationForm.markAllAsTouched();
return;
}
this.isSubmitting = true;
this.successMessage = '';
this.errorMessage = '';
const data = this.registrationForm.getRawValue();
this.studentService.registerStudent(data).subscribe({
next: () => {
this.successMessage = 'Registration saved successfully.';
this.registrationForm.reset({ name: '', email: '', course: 'Angular' });
},
error: () => {
this.errorMessage = 'Something went wrong. Please try again.';
},
complete: () => {
this.isSubmitting = false;
}
});
}
Checkpoint
Complete all checks to continue.
12. Reset Form after Submit
After successful submission, you may want to clear the form or restore default values.
Reactive Form Reset
this.registrationForm.reset({
name: '',
email: '',
course: 'Angular'
});
Template-driven Form Reset
submitTemplateForm(form: NgForm): void {
if (form.invalid) {
return;
}
console.log(form.value);
form.resetForm({ course: 'Angular' });
}
Checkpoint
Complete all checks to continue.
13. File Upload Form Submission
File upload usually uses FormData instead of a normal JSON object.
HTML
<form (ngSubmit)="submitFileForm()">
<input type="file" (change)="onFileSelected($event)">
<button type="submit" [disabled]="!selectedFile">Upload</button>
</form>
TypeScript
selectedFile: File | null = null;
onFileSelected(event: Event): void {
const input = event.target as HTMLInputElement;
if (input.files && input.files.length > 0) {
this.selectedFile = input.files[0];
}
}
submitFileForm(): void {
if (!this.selectedFile) {
return;
}
const formData = new FormData();
formData.append('file', this.selectedFile);
console.log('Ready to upload:', formData);
}
Checkpoint
Complete all checks to continue.
14. Dynamic Form Submission with FormArray
Dynamic forms allow users to add or remove fields. In reactive forms, FormArray is used for
repeated controls.
import { FormArray, FormControl, FormGroup } from '@angular/forms';
skillsForm = new FormGroup({
studentName: new FormControl('', { nonNullable: true }),
skills: new FormArray([
new FormControl('Angular', { nonNullable: true })
])
});
get skills(): FormArray<FormControl<string>> {
return this.skillsForm.controls.skills;
}
addSkill(): void {
this.skills.push(new FormControl('', { nonNullable: true }));
}
removeSkill(index: number): void {
this.skills.removeAt(index);
}
Checkpoint
Complete all checks to continue.
15. Security and Reliability Rules
Frontend validation improves user experience, but it is not enough for security. A backend must validate submitted data again.
| Rule | Reason |
|---|---|
| Validate on frontend | Helps users correct mistakes quickly. |
| Validate on backend | Prevents malicious or invalid data from being accepted. |
| Do not store secrets in Angular | Frontend code is visible after deployment. |
| Disable duplicate submit | Prevents accidental multiple requests. |
Checkpoint
Complete all checks to continue.
16. Deployment Checks for Your Angular Site
Your Angular site URL is:
https://angular.learnwithchampak.live/
For this custom domain root, use base href:
/
Build and Deploy
npm run build:github
npm run deploy:github
Recommended package.json Scripts
"build:github": "ng build --configuration production --base-href /",
"deploy:github": "ng deploy --base-href=/"
Checkpoint
Complete all checks to continue.
17. Expert Form Submission Patterns
Expert Angular form submission focuses on typed forms, services, clean state, reusable validators, error mapping, and maintainable architecture.
interface RegistrationPayload {
name: string;
email: string;
course: string;
}
function mapFormToPayload(formValue: RegistrationPayload): RegistrationPayload {
return {
name: formValue.name.trim(),
email: formValue.email.trim().toLowerCase(),
course: formValue.course
};
}
Checkpoint
Complete all checks to continue.
18. Common Mistakes
| Mistake | Problem | Fix |
|---|---|---|
Forgetting FormsModule |
ngModel does not work. |
Import FormsModule. |
Forgetting ReactiveFormsModule |
formGroup and formControlName do not work. |
Import ReactiveFormsModule. |
Using ngModel without name |
Template-driven form control may not register. | Add a unique name attribute. |
| Submitting invalid forms | Bad data enters the app. | Check form.invalid before submit. |
| No loading state | User may click submit repeatedly. | Use isSubmitting. |
Checkpoint
Complete all checks to continue.
19. Student Assignment
Create a complete form submission page called Student Registration.
Requirements
1. Create a route: /form-submission
2. Create a reactive form.
3. Fields: name, email, course, phone, message.
4. Add validators.
5. Disable submit when invalid.
6. Show error messages after touch or submit attempt.
7. Show loading text during submit.
8. Show success message after submit.
9. Reset form after successful submit.
10. Keep API call inside a service.
Final Test
ng serve
Open:
http://localhost:4200/form-submission
Final Checkpoint
Complete all checks to finish.
Final Summary
| Question | Answer |
|---|---|
| What listens to form submit? | (ngSubmit) |
| What does template-driven form need? | FormsModule |
| What does reactive form need? | ReactiveFormsModule |
| What blocks invalid submit? | Check form.invalid and return. |
| What prevents double submit? | isSubmitting and disabled submit button. |
| Where should API code go? | Inside a service. |
| How should your custom domain deploy? | ng deploy --base-href=/ |