Angular Components

A component is the fundamental building block of every Angular application. It controls a specific portion of the web page — this portion is called the component's view. An Angular application is essentially a tree of components working together to display content and respond to user actions.

Each component is self-contained. It has its own data (stored in a TypeScript class), its own display logic (written in an HTML template), and its own visual styling (optional CSS). This separation makes components reusable — the same component can appear in multiple places throughout the application.

Anatomy of a Component

Every Angular component has three core parts that always work together.

The TypeScript Class

The TypeScript class holds the component's data (properties) and behavior (methods). This is the "brain" of the component. It defines what data exists and what happens when the user interacts with the view.

The HTML Template

The HTML template defines what the component displays on the screen. It is standard HTML enhanced with Angular-specific syntax for displaying data and handling user interactions.

The Component Decorator

The @Component decorator is a special annotation placed above the TypeScript class. It links the class to its HTML template and CSS file, and defines the component's selector — the custom HTML tag used to place this component anywhere in the application.

Creating a Component with the Angular CLI

The Angular CLI provides a command to generate a new component with all the required files automatically:


ng generate component components/user-card

This can also be shortened to:


ng g c components/user-card

The CLI creates four files inside a new folder called user-card:


src/app/components/user-card/
├── user-card.component.ts
├── user-card.component.html
├── user-card.component.css
└── user-card.component.spec.ts

The CLI also automatically adds the component to the declarations array in AppModule, so it is ready to use immediately.

Understanding the Component Files

user-card.component.ts


import { Component } from '@angular/core';

@Component({
  selector: 'app-user-card',
  templateUrl: './user-card.component.html',
  styleUrls: ['./user-card.component.css']
})
export class UserCardComponent {
  userName = 'Sarah Johnson';
  userRole = 'Software Developer';
  isActive = true;
}
selector

The selector is the custom HTML tag that represents this component. Wherever <app-user-card> appears in an HTML template, Angular replaces it with the component's content.

templateUrl

This points to the HTML file that contains the component's template. An alternative is to use template (without "Url") and write the HTML directly as a string inside the decorator — useful for very short templates.

styleUrls

This is an array pointing to the CSS files for this component. Styles written here apply only to this component and do not affect other components — this is called view encapsulation.

user-card.component.html


<div>
  <h3>{{ userName }}</h3>
  <p>Role: {{ userRole }}</p>
  <p>Status: {{ isActive ? 'Active' : 'Inactive' }}</p>
</div>

The double curly braces {{ }} display the value of a property from the TypeScript class. This is called interpolation. The expression isActive ? 'Active' : 'Inactive' is a ternary expression — it displays "Active" if isActive is true, and "Inactive" if false.

Using a Component Inside Another Component

To display the UserCardComponent inside the main application, use its selector tag in any template:


<!-- app.component.html -->
<h1>Team Members</h1>
<app-user-card></app-user-card>
<app-user-card></app-user-card>
<app-user-card></app-user-card>

This places three instances of UserCardComponent on the page. Currently, all three display the same data because the data is hardcoded inside the component. Passing different data to each instance is done using @Input(), which is covered in the next section.

Component Properties and Methods

A component's TypeScript class can hold properties (data) and methods (actions). Both are accessible in the HTML template.


// counter.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-counter',
  templateUrl: './counter.component.html'
})
export class CounterComponent {
  count = 0;          // Property — stores data

  increment() {       // Method — performs an action
    this.count++;
  }

  decrement() {
    this.count--;
  }

  reset() {
    this.count = 0;
  }
}

<!-- counter.component.html -->
<h2>Counter: {{ count }}</h2>
<button (click)="increment()">+ Add</button>
<button (click)="decrement()">- Subtract</button>
<button (click)="reset()">Reset</button>

The (click)="increment()" syntax is Angular's event binding. It calls the increment() method in the TypeScript class whenever the button is clicked. The count value on screen updates automatically each time a button is clicked.

Passing Data with @Input()

The @Input() decorator allows a parent component to pass data into a child component. This makes components dynamic and reusable with different data.


// product-card.component.ts
import { Component, Input } from '@angular/core';

@Component({
  selector: 'app-product-card',
  templateUrl: './product-card.component.html'
})
export class ProductCardComponent {
  @Input() productName: string = '';
  @Input() price: number = 0;
}

<!-- product-card.component.html -->
<div>
  <h3>{{ productName }}</h3>
  <p>Price: ${{ price }}</p>
</div>

<!-- app.component.html — Parent template -->
<app-product-card productName="Bluetooth Speaker" [price]="29.99"></app-product-card>
<app-product-card productName="USB Hub" [price]="14.99"></app-product-card>

Each app-product-card receives different data. The square brackets [price] around the attribute tell Angular to treat the value as a JavaScript expression rather than a plain string — this is called property binding.

Sending Events with @Output()

The @Output() decorator allows a child component to send data or events back to its parent component. This is done using an EventEmitter.


// like-button.component.ts
import { Component, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'app-like-button',
  template: '<button (click)="sendLike()">Like</button>'
})
export class LikeButtonComponent {
  @Output() liked = new EventEmitter<string>();

  sendLike() {
    this.liked.emit('User clicked like!');
  }
}

<!-- parent.component.html -->
<app-like-button (liked)="handleLike($event)"></app-like-button>
<p>{{ message }}</p>

// parent.component.ts
export class ParentComponent {
  message = '';

  handleLike(event: string) {
    this.message = event;
  }
}

When the Like button is clicked, sendLike() calls this.liked.emit(), which fires the liked event. The parent listens with (liked)="handleLike($event)" and receives the emitted value through $event.

Component Lifecycle

Angular components go through a series of stages from creation to destruction. Angular provides lifecycle hook methods that allow developers to run code at specific stages.

The Most Common Lifecycle Hooks

ngOnInit()

Runs once after the component is created and its inputs are set. This is the most commonly used hook — ideal for fetching initial data from an API or performing setup tasks.

ngOnChanges()

Runs every time an @Input() property receives a new value from the parent component.

ngOnDestroy()

Runs just before the component is removed from the screen. Use this to clean up subscriptions or timers to prevent memory leaks.


import { Component, OnInit, OnDestroy } from '@angular/core';

@Component({
  selector: 'app-news-feed',
  templateUrl: './news-feed.component.html'
})
export class NewsFeedComponent implements OnInit, OnDestroy {
  articles: string[] = [];

  ngOnInit() {
    // Fetch data when component loads
    this.articles = ['Article 1', 'Article 2', 'Article 3'];
    console.log('Component initialized');
  }

  ngOnDestroy() {
    // Clean up when component is removed
    console.log('Component destroyed');
  }
}

Inline Template vs External Template File

Angular supports two ways to define a component's template:

External Template (Recommended for most cases)


@Component({
  selector: 'app-example',
  templateUrl: './example.component.html'  // Points to a separate file
})

Inline Template (Suitable for very small components)


@Component({
  selector: 'app-greeting',
  template: '<h2>Hello, {{ name }}!</h2>'  // HTML written directly here
})
export class GreetingComponent {
  name = 'Angular';
}

Summary

Components are the core building blocks of Angular applications. Each component consists of a TypeScript class, an HTML template, and optional CSS. The @Component decorator links these parts together and defines the component's selector. The CLI command ng generate component creates all required files automatically. Properties and methods in the class are accessible in the template. @Input() allows parent components to send data to child components. @Output() with EventEmitter allows child components to communicate back to parents. Lifecycle hooks like ngOnInit() and ngOnDestroy() provide control over what happens at each stage of the component's life.

Leave a Comment

Your email address will not be published. Required fields are marked *