Angular is one of the powerful front-end frameworks which works on component-driven architecture. Let’s address the basics and types of components, which are the building blocks of Angular. decorator is used to decorate any entity as a component. There are two types of components: stateful and stateless. A stateful component can store and change the information regarding the component state. It keeps track of all changes and reflects respective changes to associated components. Whereas a stateless component does not keep track of state changes, never directly reflects changes across associated components, and calculates internally. Now that we have the essential knowledge about Angular components we are ready to explore how to pass data into an Angular component and understand the basis of the component architecture.
Firstly, we have to create a custom property to pass the data into a component. This can be done via input binding, which passes data from one component to another, generally from parent to child. This custom input binding is created by using the decorator. For better understanding, we’ll use the stateful component that keeps track of the counter named
CounterComponent
.
First of all, we create our new component.
ng generate component counter
We then register our new CounterComponent
in (in app.module.ts file) that allows us to use it inside our components registered in
.
Now in AppComponent
we can add CounterComponent as a custom element inside the template -
app.component.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import {
Component
} from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: `
<div class="app">
<app-counter></app-counter>
</div>
`,
})
export class AppComponent {
initial_value: number = 0;
}
When we do not use the built-in properties and want to create custom properties, then we have to tell Angular the name of the property binding. So, let’s set a property binding named count on our component and supply the value of initial_value (which can be any number, in our case, it’s 0).
app.component.ts ( import statement is not mentioned )
1
2
3
4
5
6
7
8
9
10
11
12
@Component({
selector: 'app-root',
templateUrl: `
<div class="app">
<app-counter [count]="initial_value" ></app-counter>
</div> `
})
export class AppComponent {
initial_value: number = 5;
}
By using AppComponent
we pass our counter data into CounterComponent
in which we handle and mutate our data locally and get data back out.
Let’s handle the incoming data in CounterComponent
.
counter.component.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import {
Component,
Input,
OnInit
} from '@angular/core';
@Component({
selector: 'app-counter',
templateUrl: `
<div class="counter">
<span>Current Counter : {{count}}</span>
<div class="controls">
<button class="increment" (click)="incrementCounter()">
+ </button>
<button class="decrement" (click)="decrementCounter()">
- </button>
</div>
</div>
`,
styleUrls: ['./counter.component.css']
})
export class CounterComponent {
@Input()
count: number = 0;
incrementCounter() {
this.count++;
}
decrementCounter() {
this.count--;
}
}
Count behaves like a normal variable unless we do not decorate count using decorator. This decorator tells Angular to treat count as an input binding, if any data is supplied through that property binding then that data is used to initialize count, otherwise default value is taken as 0 (count: number = 0),
In our case, we passed the value of initial_value (five) with a wrapper of count as data from app.component.ts to counter.component.ts. As we decorated count in the child component using decorator, the value of count is initialized with five ([count]=“initial_value” for initial_value = 5)
In the template section of counter.component.ts, we wrote some HTML just to visualize the work we’ve done so far. If you are following everything correctly then just do ng serve
in the directory where your Angular application resides and after successful compilation of the application you can open it on the browser at http://localhost:4200/
Initially, when the value of initial_value is 5 -
If you use the same style you can paste the CSS code given below-
counter.component.css
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
.counter {
height: 100 vh;
width: 100 vw;
margin: 0;
text - align: center;
display: flex;
flex - direction: column;
justify - content: center;
align - content: center;
font - size: 2 em;
font - weight: 600;
background - color: #1a1a1a;
color: white;
font-family: 'Segoe UI';
}
.controls{
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
}
.controls button{
height: 50px;
width: 50px;
margin: 20px;
font-size: 30px;
}
In the counter application we introduced two buttons with the functionality of increment and decrement of the counter. Basically, the (+)button is for increment of the counter, we call incrementCounter()
function whenever (click) event is fired, and in that function, we simply increase the value of the count by one. Similarly, upon clicking the (-)button,(click) event is fired and we call decrementCounter() function, which simply decreases the counter by one. We also bind the count variable in the template by using {{count}}, which means the visual updates whenever the value of count is changed. Therefore, when we click on the (+) or (-) buttons the value of count will change and we can see changes on the browser as well.
On increment when (count = 5) -
On decrement when (count = 5) -
As many times as we click on that button, the value of the count changes and updates the visual as well. So, that’s all we need to do to pass the data into a component. We can create as many inputs as we want according to the needs of an application.
Let’s assume we have two components, ParentComponent
and ChildComponent
, in which we want to pass data. To pass data from ParentComponent
to ChildComponent
we first have to set property binding of any name, let it be property, and supply some data to it, let it be data.
This can be done in the ParentComponent
like this -
<ChildComponentSelector [property]=data> </ChildComponentSelector>
Now catch that bound data in ChildComponent
using decorator. For multiple inputs, set multiple property bindings on
ChildComponentSelector
in ParentComponent
and catch the same in ChildComponent
with multiple . Each will catch a single incoming property.
1 2
@Input() property: data_type = default_data