Professional Documents
Culture Documents
Unit 5-Forms and Routing in Angular 4.0
Unit 5-Forms and Routing in Angular 4.0
We make a basic form component with a basic form template and a simple
component, just like the user profile form component we started with in this
section:
Create a project
1. ng new angular-forms
1. cd angular-forms
Now, use the Angular CLI command ng generate class Hero to generate a new
class named Hero:
The app.module.ts file is used to define the application's root module. The
template-driven forms reside in their own module. You need to add the
FormsModule to the array of imports for the application module before using
forms.
1. <app-hero-form></app-hero-form>
Create an initial HTML form template
1. <div class="container">
2. <h1>Hero Form</h1>
3. <form>
4. <div class="form-group">
5. <label for="name">Name</label>
6. <input type="text" class="form-control" id="name" required>
7. </div>
8. <div class="form-group">
9. <label for="alterEgo">Alter Ego</label>
10. <input type="text" class="form-control" id="alterEgo">
11. </div>
12. <button type="submit" class="btn btn-success">Submit</button>
13. </form>
14.</div>
Style the form
Open style.css and use the following code to import the bootstrap file.
1. @import url('https://unpkg.com/bootstrap@3.3.7/dist/css/
bootstrap.min.css');
Add power list by using *ngFor
The hero form can choose power lists from a fixed list of agency-approved
powers. Use the following HTML code immediately below the Alter Ego group
in hero-form.component.html
1. <div class="form-group">
2. <label for="power">Hero Power</label>
3. <select class="form-control" id="power" required>
4. <option *ngFor="let pow of powers" [value]="pow">{{pow}}</
option>
5. </select>
6. </div>
The basic template-driven form is completed now. You can use the ng serve
command to run the project.
OUTPUT:
Directives
Terminology
Here, we've connected [(ngModel)] with the name, so whatever changes we will
do it will be stored in the name variable.
On the other side, we use the [propertyName]= "foo" syntax to create one-way
data binding by setting the value of the property.
Domain Model
Now let's bind all our input controls to our userObj directly, like so:
Form Errors
1. Handle form submission with ngSubmit and error handling in the submit
function.
2. Add a feature that disables the submit button at first and enables it only
after the form has been validated.
Sub-Form Components
When we use the <form>, the ngForm directive constructs the top Level
FormGroup behind the scenes.
Using the ngModelGroup directive, we can create a new FormGroup. Let us add
the street, city, and Pincode form control to the address FormGroup.
Simply wrap the fields within a div element with the ngModelGroup directive
applied to it, as seen below:
Launch the app and submit it. The resulting item is seen below.
Validation
The validators in the model-driven method were defined via code in the
component.
Except for the language, all of the fields were necessary, so we'll just add the
required attribute to those input fields.
Validation Styling
To provide visuals on the screen, we employ several Form Control States such
as valid, touched, and dirty. These are the FormControl properties.
Now, we can access the control state of the title using just firstName.valid, as
shown below.
Validation Messages
In terms of form validation messages, we may utilize them the same way as in
model-driven forms. We may use the same HTML in our template-driven forms
as long as we name the local reference variables the same as the form controls
in the model-driven method, as seen below:
We may submit the form using the ngSubmit directive or on the Submit button's
click event. Either option is acceptable.
user-profile.component.html
user-profile.component.ts
As with the template-driven form, we may reset the form. As seen below,
Conclusion
Reactive forms use an explicit and immutable approach to manage the state of
the form at a given point of time. When we change the form state, it returns a
new state which manages the integrity of the models between changes. In
reactive forms, you build your own representation of a form in the component
class.
Reactive forms are easy to test because they assure consistent and predictable
data when requested.
In this section, we will describe how to add a single form control. Here, the
users have to enter their name into an input field, form captures that input value,
and displays the current value of the form control element.
First, generate a component for the control by using the following syntax:
To register a single form control, you have to import the FormControl class into
your component and create a new instance of the form control to save as a class
property. The FormControl class is the basic building block used in reactive
forms.
After creating the control in the component class, you have to add it to the form
control element in the template. Use the formControl binding provided by
FormControlDirective to update the template with the form control.
1. <label>
2. Name:
3. <input type="text" [formControl]="name">
4. </label>
We have registered the form control to the name input element in the template.
Now, the form control and DOM element communicate with each other and the
view reflects changes in the model, and the model reflects changes in the view.
Add the form control component to the template to display the form. Add the
following code to app.component.html.
1. <app-name-editor></app-name-editor>
CUSTOM VALIDATORS
Usage:
Now if form control has invalid symbols we will see error message
Now, let’s assume our validator depends on the value of another form control. A
good example is the password confirmation input
Lastly, you can display an error message in your template when the passwords
don’t match:
In the template, we use the *ngIf directive to display an error message when the
'confirmPassword' field has the 'passwordMismatch' error set, indicating that the
passwords do not match.
With this custom validation in place, your Angular registration form will ensure
that the user enters the same password in both the ‘password’ and
‘confirmPassword’ fields
Asynchronous Custom Validator
Html
<mat-form-field>
<mat-label>User name</mat-label>
<input matInput type="text" placeholder="Name" formControlName="name" />
<mat-error *ngIf="userForm.controls['name'].hasError('usernameTaken')">
Username is taken
</mat-error>
</mat-form-field>
Example
Conclusion
Custom validators are a powerful tool in Angular for handling complex form
validation requirements. By creating custom validators, you can tailor your
validation logic to the specific needs of your application. Whether you need to
perform synchronous or asynchronous validation, Angular provides a flexible
framework to implement and use custom validators effectively. So, don’t
hesitate to leverage custom validators to enhance the user experience in your
Angular applications.
Modularizing your application makes it easier to reuse, configure and test the
components in your application. Following are the core types of objects and
components:
o value
o factory
o service
o provider
o constant
These objects and components can be injected into each other using AngularJS
Dependency Injection.
Value
1. //define a module
2. var myModule = angular.module("myModule", []);
3. //create a value object and pass it a data.
4. myModule.value("numberValue", 100);
5. myModule.value("stringValue", "abc");
6. myModule.value("objectValue", { val1 : 123, val2 : "abc"} );
Here, values are defined using the value() function on the module. The first
parameter specifies the name of the value, and the second parameter is the value
itself. Factories, services and controllers can now reference these values by their
name.
Injecting a value
To inject a value into AngularJS controller function, add a parameter with the
same when the value is defined.
Factory
Let's take an example that defines a factory on a module, and a controller which
gets the factory created value injected:
To inject a value into AngularJS controller function, add a parameter with the
same when the value is defined.
Service
1. //define a module
2. var mainApp = angular.module("mainApp", []);
3. ...
4. //create a service which defines a method square to return square of a nu
mber.
5. mainApp.service('CalcService', function(MathService){
6. this.square = function(a) {
7. return MathService.multiply(a,a);
8. }
9. });
10.//inject the service "CalcService" into the controller
11.mainApp.controller('CalcController', function($scope, CalcService, defau
ltInput) {
12. $scope.number = defaultInput;
13. $scope.result = CalcService.square($scope.number);
14. $scope.square = function() {
15. $scope.result = CalcService.square($scope.number);
16. }
17.});
Provider
1. //define a module
2. var mainApp = angular.module("mainApp", []);
3. ...
4. //create a service using provider which defines a method square to return
square of a number.
5. mainApp.config(function($provide) {
6. $provide.provider('MathService', function() {
7. this.$get = function() {
8. var factory = {};
9. factory.multiply = function(a, b) {
10. return a * b;
11. }
12. return factory;
13. };
14. });
15.});
Constants
You cannot inject values into the module.config() function. Instead constants
are used to pass values at config phase.
1. <!DOCTYPE html>
2. <html>
3. <head>
4. <title>AngularJS Dependency Injection</title>
5. </head>
6. <body>
7. <h2>AngularJS Sample Application</h2>
8.
9. <div ng-app = "mainApp" ng-controller = "CalcController">
10. <p>Enter a number: <input type = "number" ng-model = "number"
/></p>
11. <button ng-click = "square()">X<sup>2</sup></button>
12. <p>Result: {{result}}</p>
13. </div>
14.
15. <script src = "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/
angular.min.js"></script>
16.
17. <script>
18. var mainApp = angular.module("mainApp", []);
19.
20. mainApp.config(function($provide) {
21. $provide.provider('MathService', function() {
22. this.$get = function() {
23. var factory = {};
24.
25. factory.multiply = function(a, b) {
26. return a * b;
27. }
28. return factory;
29. };
30. });
31. });
32.
33. mainApp.value("defaultInput", 10);
34.
35. mainApp.factory('MathService', function() {
36. var factory = {};
37.
38. factory.multiply = function(a, b) {
39. return a * b;
40. }
41. return factory;
42. });
43.
44. mainApp.service('CalcService', function(MathService){
45. this.square = function(a) {
46. return MathService.multiply(a,a);
47. }
48. });
49.
50. mainApp.controller('CalcController', function($scope, CalcService,
defaultInput) {
51. $scope.number = defaultInput;
52. $scope.result = CalcService.square($scope.number);
53.
54. $scope.square = function() {
55. $scope.result = CalcService.square($scope.number);
56. }
57. });
58. </script>
59. </body>
60.</html>
The term consists of two keywords, which help demystify the concept:
Dependencies come in various shapes and forms. They are essential for a
component to work but are not part of the component itself. APIs,
libraries, databases, and other components can all act as dependencies.
There are several key reasons to use dependency injection. Some of the main
benefits include:
Constructor Injection
Use constructor injection when the dependencies are required for a class or
object to function. The dependencies are injected during class or object
instantiation and make dependencies immediately available to a class or object
instance.
Setter Injection
Method Injection
3. Injector. Creates and manages service instances and injects them into clients.
The injector resolves all dependencies and connects components as required.
Advantages
Disadvantages