How to Create Angular Component
How to Create Angular Component Angular is one of the most powerful and widely adopted front-end frameworks for building dynamic, scalable web applications. At the heart of every Angular application lies the component — a fundamental building block that encapsulates HTML, CSS, and TypeScript logic into reusable, self-contained units. Understanding how to create Angular components is not just a tec
How to Create Angular Component
Angular is one of the most powerful and widely adopted front-end frameworks for building dynamic, scalable web applications. At the heart of every Angular application lies the component a fundamental building block that encapsulates HTML, CSS, and TypeScript logic into reusable, self-contained units. Understanding how to create Angular components is not just a technical skill; its the cornerstone of effective Angular development. Whether youre building a simple landing page or a complex enterprise application, components allow you to structure your code in a modular, maintainable, and testable way.
Creating Angular components correctly ensures better performance, easier debugging, and seamless collaboration across development teams. This tutorial provides a comprehensive, step-by-step guide on how to create Angular components from scratch, including best practices, essential tools, real-world examples, and answers to common questions. By the end of this guide, youll have a solid foundation for building robust Angular applications using components effectively.
Step-by-Step Guide
Prerequisites
Before diving into component creation, ensure you have the following tools installed on your system:
- Node.js (version 18 or higher recommended)
- npm (Node Package Manager), which comes bundled with Node.js
- Angular CLI (Command Line Interface), the official tool for scaffolding and managing Angular projects
To install Angular CLI globally, open your terminal and run:
npm install -g @angular/cli
Verify the installation by checking the version:
ng version
If you see the version number (e.g., 17.x.x), youre ready to proceed.
Step 1: Create a New Angular Project
The first step in creating a component is to have an Angular project. If you dont already have one, generate a new project using Angular CLI:
ng new my-angular-app
The CLI will prompt you to choose options:
- Would you like to add Angular routing? ? Choose No for simplicity, or Yes if you plan to use navigation.
- Which stylesheet format would you like to use? ? Select CSS (you can switch to SCSS or Sass later if preferred).
Once the project is generated, navigate into the project folder:
cd my-angular-app
Start the development server:
ng serve
Open your browser and visit http://localhost:4200. You should see the default Angular welcome page.
Step 2: Generate a New Component
Angular CLI provides a powerful command to generate components automatically. This ensures proper file structure, naming conventions, and boilerplate code.
To create a new component, run:
ng generate component my-first-component
Or use the shorthand:
ng g c my-first-component
Angular CLI will create the following files inside a new folder named my-first-component:
my-first-component.component.tsThe TypeScript class defining the components logicmy-first-component.component.htmlThe template defining the components viewmy-first-component.component.cssThe stylesheet for styling the componentmy-first-component.component.spec.tsA unit test file for testing the component
Additionally, Angular CLI automatically registers the new component in the app.module.ts file (for Angular versions before 14) or in the app.component.html and component tree (for Angular 14+ with standalone components).
Step 3: Understand the Component Structure
Open the generated my-first-component.component.ts file. It will look like this:
import { Component } from '@angular/core';
@Component({
selector: 'app-my-first-component',
templateUrl: './my-first-component.component.html',
styleUrls: ['./my-first-component.component.css']
})
export class MyFirstComponentComponent {
constructor() { }
}
Lets break down each part:
- Import Statement:
import { Component } from '@angular/core';This imports theComponentdecorator from Angulars core library, which is required to define a component. - @Component Decorator: This is a TypeScript decorator that tells Angular this class is a component. It accepts an object with three key properties:
- selector: The custom HTML tag used to insert this component into other templates. By convention, it starts with
app-followed by a kebab-case name. - templateUrl: The path to the HTML template file.
- styleUrls: An array of paths to CSS files for styling the component.
- Exported Class:
export class MyFirstComponentComponentThe class that contains the components logic. The class name typically matches the component name with the word Component appended.
Step 4: Modify the Component Template
Now, open my-first-component.component.html and replace its content with:
<div class="component-wrapper">
<h3>Welcome to My First Angular Component!</h3>
<p>This component was generated using Angular CLI.</p>
</div>
This simple template displays a heading and a paragraph. Angular will render this content wherever the component is used.
Step 5: Style the Component
Open my-first-component.component.css and add some basic styling:
.component-wrapper {
padding: 20px;
border: 1px solid
ddd;
border-radius: 8px;
background-color:
f9f9f9;
margin: 20px 0;
}
.component-wrapper h3 {
color:
333;
margin-bottom: 8px;
}
.component-wrapper p {
color:
666;
}
These styles are scoped to this component by default due to Angulars View Encapsulation. This means they wont leak into other components, preventing unintended styling conflicts.
Step 6: Use the Component in the Parent Template
To display your new component, open app.component.html and add the components selector:
<app-my-first-component></app-my-first-component>
Save the file. Angulars live reload feature will automatically update the browser, and you should now see your component rendered on the page.
Step 7: Add Interactivity with TypeScript
Lets make the component interactive. In my-first-component.component.ts, add a property and a method:
import { Component } from '@angular/core';
@Component({
selector: 'app-my-first-component',
templateUrl: './my-first-component.component.html',
styleUrls: ['./my-first-component.component.css']
})
export class MyFirstComponentComponent {
message: string = 'Click the button below!';
count: number = 0;
incrementCount() {
this.count++;
}
}
Now update the template (my-first-component.component.html) to include a button and display the count:
<div class="component-wrapper">
<h3>Welcome to My First Angular Component!</h3>
<p>{{ message }}</p>
<p>Count: {{ count }}</p>
<button (click)="incrementCount()">Increment Count</button>
</div>
Here, were using:
- Interpolation:
{{ message }}and{{ count }}to display dynamic data. - Event Binding:
(click)="incrementCount()"to bind a click event to the method.
Test it in the browser. Click the button the count should increase with each click.
Step 8: Use Input and Output Properties (Advanced)
Components often need to communicate with their parent components. This is done using Input and Output decorators.
Update my-first-component.component.ts:
import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-my-first-component',
templateUrl: './my-first-component.component.html',
styleUrls: ['./my-first-component.component.css']
})
export class MyFirstComponentComponent {
@Input() title: string = 'Default Title';
@Output() countChanged = new EventEmitter<number>();
count: number = 0;
incrementCount() {
this.count++;
this.countChanged.emit(this.count);
}
}
In the template, update the heading to use the input:
<div class="component-wrapper">
<h3>{{ title }}</h3>
<p>Count: {{ count }}</p>
<button (click)="incrementCount()">Increment Count</button>
</div>
Now, in app.component.html, pass data to the component:
<app-my-first-component
title="My Interactive Component"
(countChanged)="onCountChange($event)">
</app-my-first-component>
<p>Parent received count: {{ parentCount }}</p>
And in app.component.ts:
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
parentCount: number = 0;
onCountChange(value: number) {
this.parentCount = value;
}
}
Now, when the child component emits a count change, the parent component receives and displays it. This pattern is essential for building reusable, decoupled components.
Best Practices
Follow Angular Naming Conventions
Consistency in naming improves code readability and maintainability. Use kebab-case for component selectors (e.g., app-user-card), PascalCase for class names (e.g., UserCardComponent), and camelCase for properties and methods (e.g., getUserData()).
Keep Components Focused and Single-Purpose
Each component should have one clear responsibility. Avoid creating god components that handle too many tasks. For example, separate a user profile display from a user edit form. This makes components easier to test, reuse, and debug.
Use Input and Output for Parent-Child Communication
Always prefer @Input() and @Output() over direct DOM manipulation or shared services for simple parent-child communication. This makes your components interface explicit and predictable.
Use OnPush Change Detection When Possible
By default, Angular checks every component for changes on every event. For components that receive data via inputs and dont mutate state internally, use ChangeDetectionStrategy.OnPush:
@Component({
selector: 'app-user-card',
templateUrl: './user-card.component.html',
styleUrls: ['./user-card.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush
})
This improves performance by skipping change detection unless the input references change.
Use Template Reference Variables and Local Variables
Use in templates to reference DOM elements or child components:
myInput
<input username type="text" placeholder="Enter name" />
<button (click)="logInput(username.value)">Log</button>
This avoids unnecessary dependency injection and keeps logic closer to the view.
Organize Files by Feature, Not Type
Instead of grouping all components, services, and pipes into separate folders, organize them by feature or module:
src/app/
??? user/
? ??? user-profile.component.ts
? ??? user-profile.component.html
? ??? user-profile.component.css
? ??? user-service.ts
? ??? user.model.ts
??? product/
? ??? product-list.component.ts
? ??? product-card.component.ts
? ??? product.service.ts
??? shared/
??? header.component.ts
This structure scales better and makes it easier to locate all related files for a feature.
Use Angular CLI for Generation
Always use ng generate to create components, services, pipes, and directives. This ensures consistent structure, proper imports, and avoids manual errors.
Write Unit Tests
Every component should have a corresponding test file. Use Jasmine and Karma (included by default) to test component behavior:
it('should display the title', () => {
const fixture = TestBed.createComponent(MyFirstComponentComponent);
fixture.detectChanges();
const compiled = fixture.nativeElement;
expect(compiled.querySelector('h3').textContent).toContain('Welcome');
});
Testing components early prevents regressions and increases confidence in refactoring.
Avoid Direct DOM Manipulation
Never use document.getElementById() or querySelector() inside components. Use Angulars template references, ViewChild, or Renderer2 instead for safe DOM interactions.
Use ngIf and ngFor Efficiently
Prefer structural directives like *ngIf and *ngFor over conditional rendering in TypeScript. They are optimized by Angulars template compiler and improve performance.
Tools and Resources
Angular CLI
The Angular CLI is indispensable for component creation and project management. It automates scaffolding, builds, testing, and deployment. Use commands like:
ng generate componentCreate a new componentng generate serviceCreate a serviceng testRun unit testsng buildBuild for productionng lintRun ESLint for code quality
Angular DevTools (Browser Extension)
Install the Angular DevTools Chrome extension. It allows you to inspect component trees, view inputs/outputs, and monitor change detection in real time invaluable for debugging complex applications.
VS Code Extensions
Enhance your development experience with these VS Code extensions:
- Angular Language Service Provides IntelliSense, error checking, and navigation in templates.
- Angular Snippets Quick code templates for components, directives, and pipes.
- ESLint Enforces consistent code style and catches bugs.
Official Documentation
Always refer to the official Angular documentation. Its comprehensive, regularly updated, and includes live examples. The Components section is particularly detailed and authoritative.
StackBlitz
StackBlitz is an online IDE that allows you to create, run, and share Angular projects in the browser. Its perfect for experimenting with components without local setup.
Angular Material
Angular Material provides a library of pre-built, accessible, and responsive components (buttons, dialogs, tables, etc.) that follow Googles Material Design guidelines. Use it to accelerate UI development while maintaining consistency.
NgRx (State Management)
For complex applications with shared state, consider NgRx, which implements the Redux pattern in Angular. It helps manage component state across the app in a predictable way.
Testing Tools
- Jasmine Testing framework included with Angular CLI.
- Karma Test runner that executes tests in real browsers.
- TestBed Angulars utility for testing components in isolation.
Performance Monitoring
Use Chrome DevTools Performance tab to monitor rendering, JavaScript execution, and layout shifts caused by component updates. Look for unnecessary change detection cycles and optimize with OnPush or trackBy in *ngFor.
Real Examples
Example 1: Product Card Component
Imagine youre building an e-commerce site. A product card component displays product details and allows users to add items to a cart.
product-card.component.ts
import { Component, Input } from '@angular/core';
export interface Product {
id: number;
name: string;
price: number;
image: string;
}
@Component({
selector: 'app-product-card',
templateUrl: './product-card.component.html',
styleUrls: ['./product-card.component.css']
})
export class ProductCardComponent {
@Input() product!: Product;
addToCart() {
console.log('Added to cart:', this.product.name);
}
}
product-card.component.html
<div class="product-card">
<img [src]="product.image" [alt]="product.name" />
<h4>{{ product.name }}</h4>
<p class="price">${{ product.price }}</p>
<button (click)="addToCart()">Add to Cart</button>
</div>
product-card.component.css
.product-card {
border: 1px solid e0e0e0;
border-radius: 8px;
padding: 16px;
text-align: center;
width: 200px;
margin: 10px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.product-card img {
width: 100%;
height: 120px;
object-fit: cover;
border-radius: 4px;
}
.price {
font-weight: bold;
color:
d32f2f;
margin: 8px 0;
}
button {
background-color:
1976d2;
color: white;
border: none;
padding: 8px 16px;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background-color:
1565c0;
}
Usage in parent component:
<app-product-card
[product]="{ id: 1, name: 'Wireless Headphones', price: 129.99, image: 'headphones.jpg' }">
</app-product-card>
Example 2: User Profile Component with Async Data
Components often fetch data from APIs. Heres a component that loads a user profile asynchronously.
user-profile.component.ts
import { Component, OnInit } from '@angular/core';
import { UserService } from './user.service';
export interface User {
name: string;
email: string;
avatar: string;
}
@Component({
selector: 'app-user-profile',
templateUrl: './user-profile.component.html',
styleUrls: ['./user-profile.component.css']
})
export class UserProfileComponent implements OnInit {
user: User | null = null;
loading = true;
error: string | null = null;
constructor(private userService: UserService) {}
ngOnInit(): void {
this.userService.getUser().subscribe({
next: (user) => {
this.user = user;
this.loading = false;
},
error: (err) => {
this.error = 'Failed to load user profile.';
this.loading = false;
}
});
}
}
user-profile.component.html
<div class="profile-container">
<div *ngIf="loading">Loading profile...</div>
<div *ngIf="error" class="error">{{ error }}</div>
<div *ngIf="user" class="user-details">
<img [src]="user.avatar" [alt]="user.name" />
<h3>{{ user.name }}</h3>
<p>{{ user.email }}</p>
</div>
</div>
This example demonstrates handling loading states and errors essential patterns in real-world applications.
Example 3: Reusable Modal Component
Modals are common UI elements. Create a reusable modal component that accepts content dynamically.
modal.component.ts
import { Component, Input } from '@angular/core';
@Component({
selector: 'app-modal',
templateUrl: './modal.component.html',
styleUrls: ['./modal.component.css']
})
export class ModalComponent {
@Input() title: string = '';
@Input() isOpen: boolean = false;
@Input() closeCallback: () => void = () => {};
onClose() {
this.closeCallback();
}
}
modal.component.html
<div *ngIf="isOpen" class="modal-overlay">
<div class="modal-content">
<div class="modal-header">
<h2>{{ title }}</h2>
<button (click)="onClose()">?</button>
</div>
<div class="modal-body">
<ng-content></ng-content>
</div>
</div>
</div>
Notice the <ng-content> this allows parent components to pass in arbitrary content:
<app-modal
[title]="'Confirmation'"
[isOpen]="showModal"
(close)="showModal = false">
<p>Are you sure you want to delete this item?</p>
<button (click)="deleteItem()">Delete</button>
</app-modal>
This pattern makes the modal component highly reusable across different contexts.
FAQs
What is the difference between a component and a directive in Angular?
A component is a directive with a template. All components are directives, but not all directives are components. Directives add behavior to existing elements (e.g., *ngIf, *ngFor), while components define a self-contained UI unit with its own template, style, and logic.
Can I create a component without using Angular CLI?
Yes, you can manually create the files and register the component in your module. However, this increases the risk of configuration errors and is not recommended. Angular CLI ensures proper structure, naming, and imports.
How do I share data between sibling components?
Sibling components should not communicate directly. Use a shared service with RxJS Subject or BehaviorSubject to manage state. Alternatively, pass data up to a common parent and then down to the siblings via inputs.
What is View Encapsulation in Angular?
View Encapsulation controls how CSS styles are applied to components. Angular uses Emulated (default), which scopes styles to the component by adding unique attributes. You can disable it with ViewEncapsulation.None or use ShadowDom for true CSS isolation.
Why isnt my component rendering?
Common causes:
- The selector is not used in the parent template.
- The component is not declared in the module (for non-standalone components).
- Theres a typo in the selector name (e.g.,
app-usercardvsapp-user-card). - Missing or incorrect path in
templateUrlorstyleUrls.
Can components be nested?
Yes, components can be nested arbitrarily. A parent component can include child components, which can include grandchildren, and so on. This is the foundation of component-driven architecture.
What are standalone components?
Introduced in Angular 14, standalone components can be used without being declared in an NgModule. They import dependencies directly via imports in the @Component decorator. This simplifies the architecture and is now the recommended approach for new projects.
How do I test a component with external dependencies?
Use Angulars TestBed to configure a testing module. Mock services using Jasmine spies or create fake implementations. Use compileComponents() to compile the component before testing.
Is it okay to use global CSS in Angular components?
Its discouraged. Use component-scoped styles to prevent style leakage. If you need global styles (e.g., typography, reset), place them in styles.css in the root of your project.
How do I handle form inputs in a component?
Use Angulars reactive forms (FormGroup, FormControl) or template-driven forms (ngModel). Reactive forms are preferred for complex forms due to better testability and programmatic control.
Conclusion
Creating Angular components is not merely a technical task its a foundational skill that shapes the architecture, scalability, and maintainability of your entire application. Throughout this guide, weve walked through the entire lifecycle of component creation: from setting up your environment and generating a component with Angular CLI, to implementing interactivity, managing state with inputs and outputs, applying best practices, and exploring real-world examples.
By following the structured approach outlined here prioritizing modularity, reusability, and testability youll build components that are not only functional but also easy to understand, extend, and debug. Whether youre working on a small personal project or a large enterprise system, the principles remain the same: keep components focused, communicate through well-defined interfaces, and leverage Angulars powerful tooling to your advantage.
Remember, the true power of Angular lies not in its complexity, but in its ability to turn complex UI problems into simple, composable components. As you continue your journey, challenge yourself to break down every UI element into its smallest meaningful unit. Over time, youll find that building applications becomes less about writing code and more about assembling intelligent, reusable pieces.
Now that you know how to create Angular components, the next step is to master their interactions, optimize their performance, and integrate them into larger systems. Keep experimenting, keep testing, and keep building. The world of Angular development is vast and your components are the building blocks of whats next.