Databinding In Angular
Databinding in Angular can be of 4 types:
- String Interpolation
- Property Binding
- Event Binding
- Two-Way Binding
1. String Interpolation:
Suppose we have a component called – Login and in the .ts file you have some variable like the below highlighted box:
The above variable you can use in the .html file like below:
2. Property Binding:
A little heads-up of HTML & DOM:
Before explaining about property binding, let us first see something about HTML and DOM.
In the below example the disabled attribute for the button is assigned with a false value, which is an example of an invalid attribute value, as we can not change its DOM value in any way. So the below command will not work and the button remains disabled, you have to completely remove it :
<button disabled = "false" />
But we can change it through “property binding” of Angular. How ?
For property binding we use “Square Bracket” around a property and with that Square Bracket we tell Angular that we are expecting some value for it.
[property]=”data”
<button [disabled] = "false" />
P.S.: Don’t mix String Interpolation and Property Binding.
Below 2 examples will not work:
<button [disabled] = "{{allFieldsEntered}}" /> <button [disabled] = {{allFieldsEntered}} />
Remember, within the double quotation mark of property binding you should write a TypeScript code/expression. String interpolation only work with a normal template nor within another expression of that template, nor within property binding
Demonstration example:
Lets do a demonstration to show the usage of string interpolation. The requirement is – In a login page till both the UserName and Password are entered the Login button should remain disabled. Below is the screenshot of the same:
And once you have entered all the data, the Login button is enabled:
Here is the .html file of the above screen:
The .ts file:
3. Event Binding:
Below is an example of Event Binding :
4. Two-Way Binding:
This is also called as Banana In A Box, due to its shape.
To make the ngModel to work you need to add “FormsModule” in the imports of NgModule:
Please note the difference between ngModel and NgModule.
Directives In Angular:
Directive can be defined as – instructions in the DOM. There are 3 types of directives in Angular:
- Component Directive.
- Structural Directive.
- Attribute Directive.
1. Component Directive:
This way we create angular components. These form the main class in directives. We use @Component decorator to declare these directives. These directives have a view, a stylesheet and a selector property.
2. Structural Directive:
These directives are generally used to manipulate DOM elements. Every structural directive has a ‘ * ’ sign before them. We can apply these directives to any DOM element.
*ngIf:
Below is an code snippet of its usage:
*ngFor:
It is another structural directive in Angular.
The above “todos” list can be shown in the html using *ngFor:
3. Attribute Directive:
Unlike structural directive which help in modifying the DOM elements, attribute directive help us in changing the properties (look and behaviour) of a DOM element. Most commonly used attribute directives are – ngStyle and ngClass. This helps us in creating any custom directives.
How to create a custom directive?
Execute below command in the CLI:
ng g directive blueBackground
The following code will be generated, modify it like below:
import { Directive, ElementRef } from '@angular/core'; @Directive({ selector: '[appBlueBackground]' }) export class BlueBackgroundDirective { constructor(el:ElementRef) { el.nativeElement.style.backgroundColor = "blue"; } }
And then you can use it like below:
<p appBlueBackground>Hello World!</p>
Routing In Angular:
Routing helps in navigating from one component to another component.
A use case: After the login is successful (in the login component) the user should be navigated to welcome component.
While creating the angular application you would have been asked whether you want “Routing” or not. If you would have chosen “yes” then you can see this file in your application: app-routing.module.ts:
In this file you need to add some changes like below:
Also, in app.component.html you have to comment out the login component, otherwise you will see the login component contents 2 times.
And also un-comment out the <router-outlet> tag:
Now you need to add the Router in login component’s typescript file. You need to add it through Dependency Injection. In Angular you can take help of constructor to inject the Router dependency. In Angular if you add that in the constructor it automatically become a member variable of that typescript class, you don’t have to explicitly initialize it:
Modules in Angular:
A Module is a container for a group of related components and directives, like NgModule, FormsModule, AppRoutingModule, etc.
A Component is a piece of code that represents a view. It is responsible for rendering the content and handling user interactions with the view.
In app.module.ts:
Angular Life Cycle Hooks:
Angular Life Cycle hooks are the methods that are being invoked when a component/directive is created, destroyed or changed. Below are those methods:
When a component is created its constructor is called first, still, a constructor is not part of the life cycle hooks. Angular life cycle begins only after the constructor is called. In the above pic the “red” color boxes are methods present in both Components & Directives and the “yellow” color boxes are methods present in only Components.
What is change detection ?
Change detection is a mechanism by which angular keeps the view (html) in sync with the component class (ts). The change detection will run in the below cases:
1. When the @input property changes of a component.
2. When some DOM event happens, e.g., Click or Change.
3. When a HTTP request is made.
4. When a timer event happens using setInterval()/setTimeOut()
1. ngOnChanges:
ngOnChanges() hook will be called for below 2 reason:
1. when an input bound properties (@Input() ) is detected at the start of a component.
2. when an input bound properties (@Input() ) is changed for a component.
2. ngOnInit:
This lifecycle hook is called after ngOnChanges() hook.
This is fired only once.
It is fired when we initialize some variable with a value.
3. ngDoCheck:
It will be invoked when a change detection is found or when the first time the page is loaded.
And in development mode change detection runs twice, so you can see ngDoCheck() being called twice at the first page launch.
4. ngDestroy:
It is called when the component is removed from the DOM.
All the above 3 lifecycle hooks are applicable for both Components and Directives.
Below lifecycle hooks are applicable only for Components:
5. ngAfterContentInit:
Before learning about this we should know something called – Content Projection.
Content Projection is passing some content from parent to child.
This will be required for creating reusable widgets.
In parent html :
In child html :
Template Reference Variable : Below is an example of the same:
In the .html file:
<h2 #myTemplateReferenceVariable>Template Reference Demo</h2>
In the .ts file:
//@ViewChild //You can use this or the below decorator if its a child component: @ContentChild('myTemplateReferenceVariable') someVariable : any;
Add Bootstrap To Angular Application:
First you need to install bootstrap locally to the angular project:
npm install bootstrap
This will install the latest bootstrap and it will add a new folder called bootstrap in the node_modules folder.
Then, open angular.json file and go to the style section and add the path of bootstrap.min.css file to it, like below.
(You can find the styles section inside the architect -> builder node)
"styles": [ "node_modules/bootstrap/dist/css/bootstrap.min.css", "src/styles.css" ]
Don’t forget to restart the server.
How to check whether bootstrap is added ?
If you open the developer tool and go the Elements tab, here in the head section you will see the style.css file is getting imported:
And if you go to Sources, you should find that styles.css here, and in that you can see its mentioning Bootstrap:
So that means Bootstrap is included in your project.
Angular Auth:
To create a separate Auth (Authenication & Authorization) module, we can create a Aungular service by below command:
ng g s service/auth
In this Auth service you can write your login logic.
And wherever you want to use this service you can inject this service through constructor.
what is sessionStorage ?
Window.sessionStorage is something that is associated with browser window.
What is Route Guard ?
It is a kind of Angular service that you can use to restrict (Authentication and Authorization) any particular url. This service you can share across multiple components.
Prior to Angular 14 it used to be a typescript class that used to implement from CanActivate interface, but now its a function. The class-based implementation of guards has been marked as @deprecated
in Angular documentation. Functional router guards replace the class-based approach.
The below is a class level Route Guard:
@Injectable({ providedIn: 'root' }) export class RouteGuardService implements CanActivate{ constructor(private authService:AuthService, private router:Router) { } canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot){ if(this.authService.isUserLoggedIn()){ return true; }else{ this.router.navigate(['login']); return false; } } }
Lets create a function level Route Guard. Fire the below command:
ng generate guard guard/route
On being asked, choose – CanActivate
You will see an empty function would be created.
Once we add the necessary code changes to implement the above functionality, it would be like below:
export const routeGuard2Guard: CanActivateFn = (route, state) => { const oauthService: AuthService = inject(AuthService); const router:Router = inject(Router); if (oauthService.isUserLoggedIn() ) { return true; } else{ router.navigate(['login']); return false; } };
The same screenshot:
See how we are injecting the dependencies in the function.
Then you need to do below changes in app-routing.module.ts file:
P.S.: The canActivate is a array.
Now, a question is getting popped up in my mind:
What is the difference between @Injectable and inject ?