https://github.com/dinanathsj29/angular-forms-templatedriven-tutorial
Learn Angular Forms API specially Template Driven Forms approach from basics to advanced level.
https://github.com/dinanathsj29/angular-forms-templatedriven-tutorial
angular-forms angular-template-driven-forms formsmodule ng-invalid ng-touched ng-valid ngform ngmodel ngmodelgroup template-driven-forms template-reference-variable
Last synced: 9 months ago
JSON representation
Learn Angular Forms API specially Template Driven Forms approach from basics to advanced level.
- Host: GitHub
- URL: https://github.com/dinanathsj29/angular-forms-templatedriven-tutorial
- Owner: dinanathsj29
- Created: 2019-06-26T16:59:53.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2023-01-05T20:19:14.000Z (almost 3 years ago)
- Last Synced: 2025-01-25T14:11:25.062Z (11 months ago)
- Topics: angular-forms, angular-template-driven-forms, formsmodule, ng-invalid, ng-touched, ng-valid, ngform, ngmodel, ngmodelgroup, template-driven-forms, template-reference-variable
- Language: TypeScript
- Homepage:
- Size: 8.58 MB
- Stars: 1
- Watchers: 2
- Forks: 1
- Open Issues: 12
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
Angular Template Driven Forms
=====================
Working with existing/cloned/copied Angular App
---------------------
- Clone or Download the project/app from Github or any other sources
- If using Visual Studio Code / Insiders, open Command panel/terminal from menu: View -> Terminal (shortcut key is `CTRL + BackTick` OR `COMMAND + J`)
- Go inside the project/app directory, command: `cd _examples-angular-templateDrivenForm OR cd templateDrivenForm`
- Run command: `npm install` to install project/app dependencies `(node_modules)`
- To Build and run Angular App, command: `ng serve / npm start` OR `ng serve -o` OR `ng serve --open`
- To change the port from 4200 to other port - type command: `ng serve --port 5000`
- To check the application in browser type path/URL: `localhost:4200 / 5000`
1 - Angular Forms - Introduction
=====================
1.1. Introduction to forms in Angular
---------------------
- Forms are the main, critical building block of any modern front-end Web/Mobile application
- `The real objective of forms is gathering data`
- While dealing with Forms one should create an efficient and effective workflow, User Experience (UX) and User Interface (UI) which guide users properly
- In the context of Form, the Angular framework provides support for `two-way data binding, change tracking, validation, and error handling`
#### Forms are an important and vital part of any business applications, Forms are used to:
- Authentication
- Register / Login / Profile creation
- Submit request / Place an Order
- Pay Bills
- Schedule appointments
- Also to perform many other countless data entry operations/tasks
#### As Developers while dealing with Forms, we have to perform the following tasks:
- Data binding
- Change tracking
- Validation
- Visual feedback
- Error messages
- Form submission
1.2. Prerequisites to working with Angular Forms (Basic to Intermediate knowledge):
---------------------
Basic familiarity with HTML, CSS, and JavaScript, Angular 2/4/5/6 is a must.
- HTML - Markup
- CSS - Style, Formates
- JavaScript - Behaviour, Click, Validations
- Angular - Templates, Components, Data Binding, Modules, Services, etc.
- TypeScript basics - Advanced JS features (Class, Arrow Function, Spread Operator)
- Text Editor / Visual Text Editors
1.3. Setup the Angular development environment:
---------------------
In this section, we will learn how to set up a local development environment to start developing Angular apps.
- `Node`, (website: https://nodejs.org/en)
- `NPM`, (Node Package Manager - comes inbuilt with Node)
- `Angular CLI = Command Line Interface`, Angular CLI (Command Line Interface) for angular (website: https://cli.angular.io/),
- The quickest and easiest way of starting an Angular app is through the `Angular CLI (Command Line Interface)`. It allows/helps the developer to build/generate building blocks of angular application like component, services, routings, modules, etc. with best practices quicker and easier)
- `Text Editor`
- Visual Studio Code / Visual Studio Code Insiders (website: https://code.visualstudio.com)
- Sublime Text,
- Atom,
- Brackets etc.
1.4. Anatomy / Mechanism / Concept behind Angular Forms:
---------------------
Component Template Markup `(.HTML view - Collects data)` -> Class `(.TS - Binds Data)` -> Services `(.TS Send Data)` -> Server
1.5. Angular Forms Types/techniques/strategies/approaches:
---------------------
1. **Template Driven Forms**:
- Primarily depends on the component template (manual HTML)
- Most of the code written in the component (.HTML) template file
- Template-driven forms are useful for adding a simple form to an app, such as an email list, signup form, etc.
2. **Reactive Model Driven Forms**:
- Primarily depends on the component class (dynamic)
- Majority of code written in component .ts class file
- Reactive forms are more robust, scalable, reusable, and testable
2 - Angular Template Driven Forms (TDFs)
=====================
In Template Driven forms, most of the logic/code resides in the .HTML/view/template file. The template is responsible for setting up the form, the validation, control, group etc.
2.1 Template Driven Forms (TDFs) - what is it all about?
---------------------
- Template Driven Forms (TDFs) are easy to use and similar to AngularJs (Angular 1.x) forms
- TDFs are mainly/heavily relay and depends on `Two Way Data Binding`
- The `ngModel` directives take care of actual input field values and data changes
- TDFs most of the code is a manual template, so it consists of bulky (.HTML) code/markups and minimal component code
- `ngForm` directive along with `ngModel` directive automatically tracks the form and form elements state & validity
2.2 Drawback of TDF
---------------------
- `Unit testing` is the biggest challenge (we need to run `End2End test (e2e)` with browser)
- Due to heavy markup in the template, `readability decreases and markup code looks complex`
- TDFs are `suitable for simple scenarios` only, Reactive forms are used for complex validations, unit test validations
2.3 Steps to create and use Template Driven Forms (TDFs):
---------------------
1. Create/generate new Angular CLI project
2. Add a form HTML/markup
3. Binding the Data (`ngForm` and `ngModel` directives)
4. Tracking state and validity (Add validation using `built-in validators`)
5. Providing visual Feedback (Display meaningful messages-feedbacks)
6. Displaying error messages (Display validation errors)
7. Posting data to server/`express server` (Handle form submission using `ngSubmit`)
3 - Setting up new Angular project
=====================
1. First check `angular cli` installed version details on machine by using command at command prompt: `ng -v` or `ng --version`
Image - Angular CLI version
2. If `angular CLI` not installed/available on machine (no version or error message displayed) then install it by using the command: `npm install -g @angular/cli@latest`
3. To `update/upgrade angular CLI` to the latest version, use following commands in sequence:
- command: `npm uninstall -g @angular/cli`
- command: `npm cache verify or npm cache clean`
- command: `npm install -g @angular/cli@latest`
4. Generate/create a new Angular app/project with Angular CLI - for dealing with angular forms with the syntax: `ng new appName` or `ng new project-name`, command: `ng new angular-forms-templatedriven` (after creation check the newly generated folder structure)
Image - Angular project/app folder structure
5. To run/serve the application, at command prompt type command: `ng serve` or `ng serve --port 5000` (change the port number)
6. Go to the browser and load the application by typing address: `http://localhost:4200/` or `http://localhost:5000/`
7. Add the `Bootstrap` framework to an application (CSS framework used to make cool/intuitive User Interface and look/feel)
- Download bootstrap css to local machine from bootstrap website: https://getbootstrap.com/docs/4.1/getting-started/download/ into folder `assets/library/bootstrap.min.css`
- Include bootstrap in application - index.html under `head` tag - ``
- or you can include a `CDN` path in index.html under head tag
- or else you can install bootstrap with npm command: `npm install bootstrap` and use it
Image - Bootstrap website - installation options
8. To verify bootstrap included/working properly in an application, check in Browser fonts, etc changed or not?
- Also in `app.component.html` just create any simple component like buttons or divs with bootstrap class:
- `Success Button` or
- `
Lead Heading`
- Right click on element and check in `inspect element` the bootstrap class and properties applied to respective elements
> **Syntax & Example**: index.html
```html
TemplateDrivenForms
```
4 - Adding Form Markup-Template HTML
=====================
4.1. Create an enrollment form with bootstrap classes:
---------------------
- In file `app.component.html` create a enrollment form
1. Use bootstrap classes like `form-group`, `form-control`, `form-check` and `form-check-input`, etc. with div and input field respectively to create a form fields with standard look and feel
2. Create a name and email `input` fields
3. Create a `Drop-Down` menu with `` tag and add/show drop down menu options with `*ngFor` structural directive
4. Create a `radio` button group with `` to show/select Time preference
5. Create a `checkbox` with `` to check/opt for promotional offer
- In `app.component.ts` class file
1. Create a new property `topics` to store an array of topics and to display as a select drop-down menu options
> **Syntax & Example**: app.component.html
```html
Enrollment Form
Name
Email
Phone
Choose Your Interested Topic
{{ topic }}
Time Preference
Morning
Evening
Send me promotional offers
Submit
```
> **Syntax & Example**: app.component.ts
```typescript
/* topics array */
topics = ['JavaScript', 'Angular', 'React', 'Vue'];
```
Image - Bootstrap Registration Form
Image - Bootstrap Registration Form with Drop Down Menu *ngFor
5 - Binding Data with ngForm
=====================
5.1. Angular Form - Key concepts:
---------------------
- **FormsModule**: Angluar template-driven forms are in their own module named `FormsModule`, to use the template driven form, we need to `explicitly import {FormsModule}` in our application module from `@angular/forms`
- **ngForm**: The `ngForm is an instance of the FormGroup`. The FormGroup represents the group of `FormControl` from HTML form tag, each form is a FormGroup because it will have at least one FormControl that gives us access to `(ngSubmit)` which can be bind to a method in our component and triggered when we submit the form. `The NgForm directive supplements the form element with additional features`.
- **ngModel**: We need the `ngModel in the form input, and the input must be named too`. `[(ngModel)]` follows `[(banana in the box)]` syntax and performs `two-way binding` for reading and writing input control values. If a `[(ngModel)]` directive is used, the input field takes an initial value from the bound component class and updates it back whenever any change to the input control value is detected `(on keystroke and button press)`.
- **ngModelGroup**: `ngModelGroup` is useful and helps to create group and sub-groups within forms like `ngModelGroup="address" -> and its sub child's like street, state, postal code, etc., ngModelGroup="person" -> and its sub child's name, age, gender, nationality etc.,` and so on
5.2. To start working with Angular Forms we need to follow some other steps:
---------------------
- In `app.module.ts` module class file
- import angular `FormsModule` and also include in `imports array`
- In file `app.component.html` the main markup file
- As and When we use `form tag, angular attaches its inbuilt ngForm` directive to give/pass and manage valuable information of forms
- `ngForm` directive denotes values of different fields/form-control and also values are valid or invalid
5.3. Template Reference Variable (TRF)
---------------------
- Template Reference Variable (TRF) is used to get the complete reference of the ngForm directive, we can use: ``
- Use interpolation to see/get form-control values entered: `{{ userForm.value | json }}`
- By default angular does not track each and every form-controls, to track repsective field use `ngModel` directive with respective form field
- Error will generate: *`ERROR Error: If ngModel is used within a form tag, either the name attribute must be set or the form control must be defined as 'standalone' in ngModelOptions`*
- To resolve error we must need to use `name` attribute with every input form-control with `ngModel` : ``
- Check the difference in `user form.value` object
- Enter data in every form field and again verify `userForm.value`
- We can collect and `send data to the server by using userForm.value` but the better approach is to bind data to `user defined model` and send model data to the server
> **Syntax & Example**: app.module.ts
```typescript
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
imports: [
BrowserModule,
FormsModule
]
```
> **Syntax & Example**: app.component.html
```html
Enrollment Form
Forms Values : userForm.value : {{ userForm.value | json }}
Name
Email
Phone
Choose Your Interested Topic
{{ topic }}
Time Preference
Morning
Evening
Send me promotional offers
Submit
```
Image - Template Driven Form - ngModel error
Image - Form Model, FormControl/FormGroup - defualt values
Image - Form Model, FormControl/FormGroup - updated values
6 - Binding Data to a Model
=====================
- Here will try to create `user defined model`, as soon as user will enter data will update an instance of user model and send model data to the server
- Inside the app/project folder/directory generate a new class which acts as a model with the command: `ng generate class User` or `ng g class User`
- It will generate a new file named: `user.ts`, type in the different `properties` of user class like `name, email, phone - as per fields used in the form`
- User model is ready with us now create an instance of model in `app.component.ts` with new property named `userModel` which consists of user default details/information: `userModel = new User('Dinanath', 'dinanathj@gmail.com', 9892221165, 'default', 'morning', true);`
- Custom userModel instance with data is ready in the class file now its time to `bind userModel with enrollment form using interpolation {{ userModel | JSON }}`
- To bind the userModel properties with form field use property binding denotes by a square bracket to the ngModel directive and userModel properties `[(ngModel)]="userModel.name"` and so on...
- `Property data binding by square bracket only is one-way data binding [(ngModel]` -> data flow from class to the view but not flows from view to the class
- So to implement/achieve two-way `data binding use banana in the box ie [(ngModel)]`, two-way data binding sync model and view
> **Syntax & Example**: user.ts
```typescript
export class User {
constructor(
public name: string,
public email: string,
public phone: number,
public topic: string,
public timePreference: string,
public subscribe: boolean
){}
}
```
> **Syntax & Example**: app.component.ts
```typescript
import { User } from './user';
userModel = new User('Dinanath', 'dinanathj@gmail.com', 9892221165, 'default', 'morning', true);
```
> **Syntax & Example**: app.component.html
```html
Enrollment Form
Forms Values : userForm.value : {{ userForm.value | json }}
Forms Values : userModel data : {{ userModel | json }}
Name
Email
Phone
Choose Your Interested Topic
{{ topic }}
Time Preference
Morning
Evening
Send me promotional offers
Submit
```
Image - User Class - works as Data Model
Image - User Class - formvalue, modelvalue
Image - User Class, form model, Two Way Data Binding
7 - Tracking state and validity
=====================
- As Validations are an important aspect of programming, before sending data to the server it's pretty important to `validate the form data and show user respective visual feedback or error message`
- Using `ngModel` in a form gives you more than just two-way data binding:
- It also tells you if the user touched the control (state & activity),
- If the value changed, or
- If the value became valid/invalid (validity)
- The `NgModel` directive doesn't just track state:
- It updates the control with special `Angular CSS classes that reflect the state`,
- We can leverage/utilize those class names to change the appearance of the control
7.1. Angular classes used to track control state and validity:
---------------------
Angular automatically attach classes like `ng-invalid, ng-dirty, ng-touched` to input fields
| STATE | CLASS applied
(if TRUE) | CLASS applied
(if FALSE) |
| ----------------------------------------------|-------------------|-----------------------|
| The control has been visited/clicked/touched
(`class will apply/change only on blur event`, user need to navigate away from form control) | ng-touched | ng-untouched |
| The controls value has been changed
(class will apply when user type something) | ng-dirty | ng-pristine |
| The controls value is valid | ng-valid | ng-invalid |
- Add a `#Template Reference Variable (#TRV)` named `#name` to the `Name field` and use it to display the input's CSS classes
- Use interpolation to see/get form-control classes: `{{ name.className }}`
- Right click on element and check in browser `inspect element` panel the respective angular state classes applied
> **Syntax & Example**: app.component.html (to apply state and class)
```html
Name
Angular Classes : name.className : {{ name.className }}
```
7.2. Angular classes and properties used to track control state and validity:
---------------------
- With each of the `state classes` angular also provide an alternative associated `state properties` on the ngModel directive
- properties names are the same as the class name, only `ng-` removed from it
| CLASS | PROPERTY |
| ------------------------------------------|-------------------------------------------|
| .ng-untouched | untouched |
| .ng-touched | touched |
| .ng-pristine | pristine |
| .ng-dirty | dirty |
| .ng-valid | valid |
| .ng-invalid | invalid |
- `#name` reference variable by default point to input element/field of DOM, by assigning `#name="ngModel"` will `point to ngModel` so all ngModel properties will be available to us
- Use interpolation to see/get form-control properties: `{{ name.touched }} {{ name.pristine }} {{ name.valid }}`
- Right click on element and check in browser `inspect element` panel the respective angular state classes applied with respective properties
> **Syntax & Example**: app.component.html (to apply state and properties)
```html
Name
Angular ngModel properties used for input fields: touched - {{ name.touched }} | pristine - {{ name.pristine }} | valid - {{ name.valid }}
```
Image - Form - State class - default
Image - Form - State class - changed/upated/modified
Image - Form - State Properties - default
Image - Form - State Properties - changed/upated/modified
8- Validation with Visual Feedback
=====================
- A good user experience is to visually indicate to the user `form field is valid/invalid` while feeling up the form/entering the details
- Usually one can use attributes/properties like `Required, Maxlength, Minlength and Pattern` for form validation on form input fields
- We can use Angular inbuilt validation classes or can create a custom css class and use for indication
> **Note**: bootstrap uses a class `'is-invalid'` to show a red border around input fields
> **Syntax & Example**: styles.css
```css
/* create custom css class for indicating invalid visual border */
.form-control.ng-invalid.ng-touched {
border: 1px solid coral;
box-shadow: 1px 1px 5px 1px coral;
}
```
- Check if the name is `invalid` and also `touched` (something entered and removed) then only apply a bootstrap/custom class named `'is-invalid'` but don't apply initially without touch:
- Apply pattern matching validation input only `10 digits mobile number - pattern="^\d{10}$" `
> **Syntax & Example**: app.component.html (apply validation class to show red border)
```html
Name
Phone
```
Image - Form Default properties/class
Image - Form field - show Red border
9 - Displaying Error Messages
=====================
- Its essential/advisable to show user visual red border with appropriate Error Messages/feedback
> **Note**: Bootstrap class `'d-none'` is used to `hide/display:none` for any element. We can use either `'*ngIf'` or `'class binding'` or both to display error messages.
9.1. Showing single error with a class binding:
---------------------
> **Syntax & Example**: app.component.html
```html
Name
* Name is required
Phone
Enter 10 digits mobile number
```
9.2. Showing group or multiple error messages: error property:
---------------------
- Some times we come across a scenario where we need to apply multiple validations and also we need to show a different error message
> **Syntax & Example**: app.component.html
```html
Phone
* Phone is required
* Phone number must be 10 digits
```
Image - Class binding error messages
Image - Error property showing multiple/different errors
Image - Error property showing multiple/different errors
10 - Select control validation
=====================
#### `Select option drop down menu` validation with required and showing error message: we need to listen/check `'Blur'/'Change'` event and verify option selected and accordingly set validation/show error messages:
> **Syntax & Example**: app.component.html
```html
Choose Your Interested Topic
{{ topic }}
Please choose right topic
```
> **Syntax & Example**: app.component.ts
```typescript
// class member to hold select option error state
topicHasError = true;
// select option validation
validateChoosenTopic(curValue) {
if (curValue === 'default') {
this.topicHasError = true;
} else {
this.topicHasError = false;
}
}
```
Image - Topic Select Dropdown validation
11 - Form level validation
=====================
- Whenever we add the `` tag/element in to the html page, angular automatically attaches the `'ngForm'` directive to the form tag
- We can get the reference of the `'ngForm'` directive by using `#Template Reference Variable (#TRV)`, example: ``
- Form validation properties can be used for global level operations like `enable/disable of 'SUBMIT'` button etc.
- Use interpolation to see/get form-validation status: `{{ userForm.form.valid }} `
> **Syntax & Example**: app.component.html
```html
Form Validation status : userForm.form.valid : {{ userForm.form.valid }}
Submit
```
Image - userForm.form.valid status - Success
Image - userForm.form.valid status - false/invalid
12 - Submitting form data
=====================
1. Use `'novalidate'` attribute to form tag to avoid/prevent browser `default validations` when will click on 'SUBMIT' button
- ``````
2. Bind `'ngSubmit'` event to the form tag which will trigger on 'SUBMIT' button
- ``````
3. Define `onSubmit()` event handler in `app.component.ts` class file
> **Syntax & Example**: app.component.html
```html
```
> **Syntax & Example**: app.component.ts
```typescript
// handler for submit button
onSubmit() {
console.log('submit button clicked');
console.log(this.userModel);
}
```
4. To send data to the server we need to create/use `'enrolment service'` with angular CLI by using the command: `ng generate service enrollment` or `ng g s enrollment`
- `enrollment.service.ts:`
- Import HttpClient module: import { HttpClient } from '@angular/common/http';
- Invoke HttpClient in constructor as a local variable / Dependency injection:
constructor(public _httpClient:HttpClient) { }
5. `app.module.ts: `
- import HttpClientModule: import { HttpClientModule } from '@angular/common/http';
- add to the imports array:
imports: [
BrowserModule,
FormsModule,
HttpClientModule
],
6. `enrollment.service.ts:`
- // create a variable which hold path to which will post the date
_url = 'http://localhost:3000/enroll';
- // create a method called enroll which will post the data to server
enroll(user:User){
return this._httpClient.post``(this._url,user);
}
7. `app.component.ts: `
- The Post request will return response as an `observable`, so we need to subscribe to observables in app.component.ts
- Import enrollment service: import { EnrollmentService } from './enrollment.service';
- Invoke in constructor as a local variable / Dependency injection:
constructor(public enrollmentService:EnrollmentService) { }
- On submit button clicked i.e. in onSubmit() method subscribe to the observables:
> **Syntax & Example**: app.module.ts
```typescript
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent,
],
imports: [
BrowserModule,
FormsModule,
HttpClientModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
```
> **Syntax & Example**: enrollment.service.ts
```typescript
import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { User } from './user';
@Injectable({
providedIn: 'root'
})
export class EnrollmentService {
// create a variable which holds the path to which will post the date
_url = 'http://localhost:3000/enroll';
constructor(public _httpClient: HttpClient) { }
// create a method called enroll which will post the data to the server
enroll(user: User) {
return this._httpClient.post(this._url, user)
}
}
```
> **Syntax & Example**: app.component.ts
```typescript
// handler for submit button
onSubmit() {
console.log('submit button clicked');
console.log(this.userModel);
this.enrollmentService.enroll(this.userModel)
.subscribe(
data => console.log('Success!', data),
error => console.error('Error!', error)
)
}
```
Image - Submit - Check userModel value
13 - Create Express Server to Receive Form Data
=====================
1. At the root, besides the angular application folder create a new siblings folder named `'server'` which consists of server-side code
2. Run the command: `npm init --yes` to create a `package.json` also bypass-surpass the questions with default answers (without giving answers to questions)
3. Install express and other dependencies with the command:
`npm install --save express body-parser cors`
- **express**: node web server
- **body-parse**r: middleware to read/send/pass form data (to handle form data)
- **cors**: cross origin port/domain request (helps to make request through multiple ports/servers - cross origin resource sharing)
> **Syntax & Example**: package.json
```json
"dependencies": {
"body-parser": "^1.18.3",
"cors": "^2.8.4",
"express": "^4.16.3"
}
```
4. Inside a `server` folder create a new file named `'server.js'` and required logic
5. At command prompt/terminal run command: `node server` - will get output in terminal as 'Server running on localhost port: 3000'
6. in browser type path: `'http://localhost:3000/'` - output - 'Hello from server!'
Image - Node Server Running
7. add endpoint in server.js to which angular application will post data
// add endpoint
app.post('/enroll', function(req,res){
// req.body - contains user data send by the angular
console.log(req.body);
// send response
res.status(200).send({'message': 'Data received'});
})
8. insert/add endpoint path to angular url variable in 'enrollment.service.ts'
_url = 'http://localhost:3000/enroll';
9. restart the node server by command: `node server`
10. In angular application click on the submit button and check `inspect element` console as well as node console will get the message and user data as an output. for better usability its advisable to hide actual form/hide submit button / disable submit button etc. to avoid the extra click on submit button.
> **Syntax & Example**: server.ts
```typescript
// 1. imports/requires the packages
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
// port
const PORT = 3000;
const app = express();
// handle the json data
app.use(bodyParser.json());
app.use(cors());
// test/check get request
app.get('/',function(req, res){
res.send('Hello from server!');
})
// add endpoint
app.post('/enroll', function(req,res){
// req.body - contains user data send by the angular
console.log(req.body);
// send response
res.status(200).send({'message': 'Data received'});
// to see errors
// res.status(401).send({'message': 'Data received'});
})
// listen to request
app.listen(PORT, function(){
console.log('Server running on localhost port: ', PORT);
})
```
Image - Template Driven Form - Submit Form data
Image - Template Driven Form - Submit Form data with Node Server Response
14 - Error Handling
=====================
1. To catch error we need support of `'rxjs'` operators
> **Syntax & Example**: enrollment.service.ts
```typescript
// to catch error
import { catchError } from 'rxjs/operators';
import { throwError } from 'rxjs';
// create a method called enroll which will post the data to the server
enroll(user:User){
return this.httpClient.post``(this._url,user)
.pipe(catchError(this.errorHandler)) //catch errors
}
errorHandler(error: HttpErrorResponse) {
return throwError(error);
}
```
2. By defualt we log error to console its advisable to create a new data member/property named 'errorMessage' and bind to the view.
> **Syntax & Example**: app.component.ts:
```typescript
// store error in data member / property to bind to the view
error => this.errorMessage = error.statusText
```
3. > **Syntax & Example**: app.component.html
```html
{{ errorMessage }}
```
4. in server.js change:
res.status(200) to res.status(401).send({'message': 'Data received'});
5. restart node server, load angular application application, click on submit and check
15 - TDF and Reactive (Model Driven) Approach
=====================
- `'ngForm'` directive gives us entire information (different properties/methods/objects/values used with form/form fields)
- To examine/understand just pass current form ie. `#userForm` parameter in submit button event handler function and check in `inspect element/developer tools` -> console panel:
- `NgForm` object -> form: `FormGroup` -> `controls` -> each and every form field is of type FormControl
- `FormGroup` and `FormControl` are building blocks of reactive forms
- Template Driven Form approach is behind the scene works as Model Driven approach where models are automatically created by angular
> **Syntax & Example**: app.component.html:
```html
```
> **Syntax & Example**: app.component.ts:
```ts
onSubmit(curForm) {
console.log('current User Form reactive details: ', curForm);
}
```
Image - Template Driven Form vs Module Driven/Reactive Form