Lab Exercise 3
Create a new component called "user-form" that contains a form for adding a
new user. Add form validation to the user form (e.g., required fields, email
format). Display validation errors if the user submits the form with invalid
data. Handle form submission and display the submitted user data on the
page.
Prerequisites:
• Angular CLI installed (npm install -g @angular/cli)
• An Angular project initialized
• Basic knowledge of Angular components, forms, and TypeScript
Steps to Complete the Lab Exercise
1. Create new project
ng new project-name --no-standalone
2. Generate the user-form Component
Use the Angular CLI to create a new component called user-form.
This creates the component files (user-form.component.ts, user-
form.component.html, user-form.component.css, and user-
form.component.spec.ts) in src/app/user-form.
3. Set Up Reactive Forms in the Angular Module
Since reactive forms provide better control for validation, we’ll use the
ReactiveFormsModule.
In src/app/app.module.ts, ensure the ReactiveFormsModule is imported:
Theory:
The ReactiveFormsModule is an Angular module that provides tools for
creating and managing reactive forms in an Angular application. It’s part of
Angular’s forms system and is designed to handle form logic in a more
programmatic and flexible way compared to template-driven forms.
• Purpose: It allows you to create forms in Angular where the form’s
structure, validation, and behavior are defined in the TypeScript code
(not the HTML template). This makes it easier to manage complex
forms, add dynamic validation, and test form logic.
• Part of Angular: It’s included in the @angular/forms package, which
comes with Angular when you set up a project using the Angular CLI.
• Use in Code: In the user-form component, ReactiveFormsModule was
imported in app.module.ts to enable the reactive form features,
allowing you to use FormBuilder, FormGroup, and Validators to create
the form.
4. Create the Form in the Component
Update src/app/user-form/user-form.component.ts to define a reactive form
with fields (e.g., name, email, age) and validation rules.
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
@Component({
selector: 'app-user-form',
standalone: false,
templateUrl: './user-form.html',
styleUrl: './user-form.css'
})
export class UserForm {
userForm: FormGroup; // The form object
submitted = false; // Tracks if form is submitted
userData: any = null; // Stores submitted data
constructor(private fb: FormBuilder) {
// Create form with three fields and validation
this.userForm = this.fb.group({
name: ['', Validators.required], // Name must not be empty
email: ['', [Validators.required, Validators.email]], // Email must be
valid
age: ['', [Validators.required, Validators.min(18)]], // Age must be 18 or
more
});
}
// Easy way to access form fields in the HTML
get f() {
return this.userForm.controls;
}
// Called when the form is submitted
onSubmit() {
this.submitted = true; // Mark form as submitted
// If form is invalid, stop here
if (this.userForm.invalid) {
return;
}
// Save the form data
this.userData = this.userForm.value;
console.log('Submitted Data:', this.userData); // Show data in console
// Clear the form
this.userForm.reset();
this.submitted = false; // Reset submitted state
}
}
Theory:
• FormBuilder: Simplifies creating forms.
• Validators: Rules for the form:
o name: Can’t be empty.
o email: Must be a valid email (e.g., “
[email protected]”).
o age: Must be a number 18 or higher.
• submitted: Helps show errors only after the user clicks “Submit.”
• userData: Stores the form data to display later.
• onSubmit(): Runs when the form is submitted, checks if the form is
valid, and saves the data.
Explanation:
1. Class Properties
userForm: FormGroup; // The form object
submitted = false; // Tracks if form is submitted
userData: any = null; // Stores submitted data
These are variables (properties) used to manage the form and its data.
• userForm: FormGroup: Holds the form with fields (name, email, age).
FormGroup is a class from @angular/forms that manages a group of
form fields.
• submitted = false: A boolean (true/false) that tracks whether the user
clicked the “Submit” button. It’s used to show error messages only
after submission.
• userData: any = null: Stores the form’s data (e.g., { name: 'Amit', email:
'[email protected]', age: 20 }) after a valid submission. any means it
can hold any type of data, and null means it starts empty.
2. Constructor
constructor (private fb: FormBuilder) {
// Create form with three fields and validation
this.userForm = this.fb.group({
name: ['', Validators.required], // Name must not be empty
email: ['', [Validators.required, Validators.email]], // Email must be
valid
age: ['', [Validators.required, Validators.min(18)]], // Age must be 18 or
more
});
}
The constructor runs when the component is created and sets up the form.
• private fb: FormBuilder: Injects the FormBuilder tool to create the
form. private means it’s only used inside this class.
• this.userForm = this.fb.group({...}): Creates a form with three fields:
1) name: ['', Validators.required]: The name field starts empty ('') and
must not be empty (Validators.required).
2) email: ['', [Validators.required, Validators.email]]: The email field
starts empty and must be both filled (required) and a valid email
format (e.g., “
[email protected]”).
3) age: ['', [Validators.required, Validators.min(18)]: The age field
starts empty, must be filled, and must be 18 or higher.
• Each field is a FormControl (a single input field) inside the FormGroup
(the whole form).
This sets up the form’s structure and rules before the user sees it.
3. Getter Method
get f() {
return this.userForm.controls;
}
A shortcut to access the form’s fields (controls) in the HTML.
• get f(): Creates a property called f that returns this.userForm.controls,
which is an object containing the form’s fields (name, email, age).
• In the HTML, you use f['name'] to check the name field’s status (e.g.,
f['name'].errors to see if it has errors).
• Example: f['name'].errors?.['required'] checks if the name field is empty.
It makes the HTML code shorter and easier to read when checking for errors.
4) onSubmit Method
onSubmit() {
this.submitted = true; // Mark form as submitted
// If form is invalid, stop here
if (this.userForm.invalid) {
return;
// Save the form data
this.userData = this.userForm.value;
console.log('Submitted Data:', this.userData); // Show data in console
// Clear the form
this.userForm.reset();
this.submitted = false; // Reset submitted state
Runs when the user clicks the “Submit” button in the form.
• this.submitted = true: Sets the submitted flag to true, which tells
sandwiched between the HTML to show error messages (e.g., “Please
enter a name”) if fields are invalid.
• if (this.userForm.invalid) { return; }: Checks if the form has any
validation errors (e.g., empty fields, invalid email). If it does, the
function stops (return) and doesn’t save data.
• this.userData = this.userForm.value: If the form is valid, saves the
form’s data (e.g., { name: 'Amit', email: '
[email protected]', age: 20 })
to userData for display in the HTML.
• console.log('Submitted Data:', this.userData): Prints the data to the
browser’s console for debugging (you can see it in the browser’s
Developer Tools).
• this.userForm.reset(): Clears the form’s fields so the user can enter
new data.
• this.submitted = false: Resets the submitted flag so error messages
don’t show until the next submission.
This handles what happens when the user submits the form, ensuring
only valid data is saved and displayed.
5. Create the Form Template
Update the HTML file to create the form and display errors and submitted
data.
File: src/app/user-form/user-form.component.html
<div class="form-container">
<h2>Add a New User</h2>
<!-- Form with three input fields -->
<form [formGroup]="userForm" (ngSubmit)="onSubmit()">
<!-- Name Field -->
<div>
<label>Name:</label>
<input type="text" formControlName="name">
<!-- Show errors if submitted and field is invalid -->
<div class="error" *ngIf="submitted && f['name'].errors?.['required']">
Please enter a name.
</div>
</div>
<!-- Email Field -->
<div>
<label>Email:</label>
<input type="email" formControlName="email">
<!-- Show errors for email -->
<div class="error" *ngIf="submitted && f['email'].errors?.['required']">
Please enter an email.
</div>
<div class="error" *ngIf="submitted && f['email'].errors?.['email']">
Please enter a valid email.
</div>
</div>
<!-- Age Field -->
<div>
<label>Age:</label>
<input type="number" formControlName="age">
<!-- Show errors for age -->
<div class="error" *ngIf="submitted && f['age'].errors?.['required']">
Please enter an age.
</div>
<div class="error" *ngIf="submitted && f['age'].errors?.['min']">
Age must be 18 or older.
</div>
</div>
<!-- Submit Button -->
<button type="submit">Add User</button>
</form>
<!-- Show submitted data if available -->
<div class="submitted-data" *ngIf="userData">
<h3>New User Added:</h3>
<p>Name: {{ userData.name }}</p>
<p>Email: {{ userData.email }}</p>
<p>Age: {{ userData.age }}</p>
</div>
</div>
Explanation:
• <form [formGroup]="userForm">: Connects the form to the
TypeScript code.
• formControlName: Links each input to a field in the form.
• Error Messages: Only show when submitted is true and the field has
errors (e.g., empty name or invalid email).
• Submitted Data: Shows the user’s input after a valid submission.
• *ngIf: Controls when elements (like error messages or submitted data)
appear.
6. Add Simple Styling
Update the CSS file to make the form look clean.
File: src/app/user-form/user-form.component.css
.form-container {
width: 300px;
margin: 20px auto;
padding: 10px;
}
div {
margin-bottom: 15px;
}
label {
display: block;
font-weight: bold;
}
input {
width: 100%;
padding: 5px;
border: 1px solid #ccc;
}
.error {
color: red;
font-size: 12px;
}
button {
background-color: #4CAF50;
color: white;
padding: 10px;
border: none;
cursor: pointer;
}
button:hover {
background-color: #45a049;
}
.submitted-data {
margin-top: 20px;
padding: 10px;
border: 1px solid #ccc;
background-color: #f0f0f0;
}
Explanation:
• Styles make the form neat and centered.
• Inputs are full-width with a simple border.
• Errors are red for visibility.
• The submit button is green and changes color on hover.
• Submitted data is shown in a light gray box.
7. Add the Component to the App
Replace the content of the main app template to show the user-form
component.
File: src/app/app.component.html
Explanation: This makes the user-form component appear when you run the
app.
8. Run the Application
ng serve