Reinventing the wheel is a waste of time and effort. Let's take the example of building a car. If you try to create an engine from scratch each time you build a car, it will take quite some time to produce a car.
When we are talking about code, we can take the same approach by learning how to create reusable pieces of code. By using that reusable code, you save time which helps in finishing the app faster, while still maintaining quality. Moreover, since you are using the same piece of code, it's also easier to test it.
In this article, we will explore how to create a reusable Angular Component, so that you can reduce your build time. To showcase the process we will use a list of employees, but feel free to use any other kind of data.
Now, let's get started!
Creating components in Angular
Let's start by installing the Angular CLI.
npm install -g @angular/cli
Once you have installed the Angular CLI, create a new Angular project using the CLI.
ng new angular-pro
Navigate to the project directory and start the Angular app.
cd angular-pro
npm start
You will have the Angular application running at localhost:4200
.
By default, you'll have the AppComponent
in the boilerplate code.
Let's add some dummy data to the app.component.ts
file.
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'angular-pro';
data = [{
name : 'Sam Johnson',
dept : 'Electrical'
},{
name : 'Roy Thomas',
dept : 'Mechanical'
},{
name : 'Jim Lasker',
dept : 'Medical'
}]
}
To make the application appealing, let's add bootstrap to the Angular project. From the Angular CLI execute the following command,
npm install bootstrap jquery popper.js
Now add the Bootstrap scripts and CSS files to the angular.json
file.
"styles": [
"src/styles.css",
"node_modules/bootstrap/dist/css/bootstrap.min.css"
],
"scripts": [
"node_modules/jquery/dist/jquery.min.js",
"node_modules/popper.js/dist/umd/popper.min.js",
"node_modules/bootstrap/dist/js/bootstrap.min.js"
]
Let's render a list of the data you defined in app.component.ts
file. Add the following HTML code to the app.component.html
file.
-
{{item.dept}}
{{item.name}}
14
Add the following code to the app.component.css
file.
.margin-30{
margin: 30px;
}
.font-fam{
font-family: serif;
}
Save the above changes and you'll be able to see the list of employees based on the data
in the app.component.ts
file.
Creating a reusable Angular component
You just added some code to render a list of items. As you can see in the list presented above, the total count is presented next to each item. There might be scenarios where you might not be needing the count but rather the same list. So the same code works for you with a bit of modification.
Let's make the list rendering code reusable by creating a separate component altogether. The item count can be made configurable to display or hide as per need.
Create a new component using the Angular CLI.
ng g component dataList
It will create a new component inside app/data-list
called DataListComponent
.
Move the app.component.html
and the app.component.css
code to data-list.component.html
and data-list.component.css
respectively.
For the time being, let's also move the data
to data-list.component.ts
. Eventually, you'll be passing the data to the component using @Input
decorator.
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-data-list',
templateUrl: './data-list.component.html',
styleUrls: ['./data-list.component.css']
})
export class DataListComponent implements OnInit {
data = [{
name : 'Sam Johnson',
dept : 'Electrical'
},{
name : 'Roy Thomas',
dept : 'Mechanical'
},{
name : 'Jim Lasker',
dept : 'Medical'
}];
constructor() { }
ngOnInit(): void {
}
}
Save the changes and reload your Angular application. You won't be able to see the data list rendered.
You created an Angular component to render the list. But for it to render you need to use the DataListComponent
selector app-data-list
in the app.component.html
.
Save the changes and you'll be able to see the data list.
Understanding @Input and @Output in Angular
From the official docs,
A common pattern in Angular is sharing data between a parent component and one or more child components. You can implement this pattern by using the
@[Input]()
and@[Output]()
directives.
Now, let's make it reusable by passing in data to the Angular component. You can use the @Input
decorator for passing data to the component.
Let's start by defining the @Input
decorator inside the DataListComponent
component.
import { Component, Input, OnInit } from '@angular/core';
@Component({
selector: 'app-data-list',
templateUrl: './data-list.component.html',
styleUrls: ['./data-list.component.css']
})
export class DataListComponent implements OnInit {
@Input() data;
@Input() showCount = false;
constructor() { }
ngOnInit(): void {
}
}
As seen in the above code, you have defined two @Input
decorators, one for passing the data to render and another, a Boolean, to decide whether to show count info.
In the data-list.component.html
modify the HTML to configure the data as per the @Input
parameters.
-
{{item.dept}}
{{item.name}}
14
Modify the app.component.html
file to pass the @Input
decorators to the reusable child component.
Define data1
and data2
inside the app.component.ts
file.
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'angular-pro';
data1 = [{
name : 'Sam Johnson',
dept : 'Electrical'
},{
name : 'Roy Thomas',
dept : 'Mechanical'
},{
name : 'Jim Lasker',
dept : 'Medical'
}];
data2 = [{
name : 'Johnson',
dept : 'Physics'
},{
name : 'Thomas',
dept : 'Chemistry'
},{
name : 'Lasker',
dept : 'Biology'
}];
}
Save the above changes and you will be able to see two lists of data rendered.
Next, let's add a counter to get the count of all data being displayed. Each of the DataListComponent
will check for the count of data and return to the parent component. The parent component will sum up the count of data returned from each component and display it.
You can make use of @Output
decorator to emit the count of data. Let's define one inside the DataListComponent
.
@Output() calCount = new EventEmitter();
Once the DataListComponent
has been initialized, let's emit the data count using the calCount
event emitter.
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
@Component({
selector: 'app-data-list',
templateUrl: './data-list.component.html',
styleUrls: ['./data-list.component.css']
})
export class DataListComponent implements OnInit {
@Input() data : [];
@Input() showCount = false;
@Output() calCount = new EventEmitter();
constructor() { }
ngOnInit(): void {
this.calCount.emit(this.data.length);
}
}
Modify the app.component.html
file to include the event handler.
Now once the calCount
emitter emits the data length, it will be received in the calCount
receiver method which we need to define inside the app.component.ts
file.
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'angular-pro';
totalCount = 0;
data1 = [{
name : 'Sam Johnson',
dept : 'Electrical'
},{
name : 'Roy Thomas',
dept : 'Mechanical'
},{
name : 'Jim Lasker',
dept : 'Medical'
}];
data2 = [{
name : 'Johnson',
dept : 'Physics'
},{
name : 'Thomas',
dept : 'Chemistry'
},{
name : 'Lasker',
dept : 'Biology'
}];
calCount(count){
this.totalCount = this.totalCount + count;
}
}
Let's also show the totalCount
variable inside the app.component.html
file. Here is how the final app.component.html
looks:
Total Data Count ::
{{totalCount}}
Save the changes and you will be able to see the two data lists and their total count rendered in the application.
Wrapping it up
Not every code is reusable. But there are pieces of code that can be used across the same application. In this tutorial, you learned how to create reusable Angular components and you also learned how to use the @Input
and @Output
decorators in the process.
The source code from this tutorial is available on GitHub.