In Angular, a component is the fundamental building block of the user interface (UI).
Structure of a Component
A component is made up of three main parts:
- TypeScript class – contains properties (data) and methods (logic).
- HTML template – defines what gets rendered on the page.
- CSS/SCSS styles – optional styles for that component’s template.
Each component is decorated with the @Component
decorator, which tells Angular how to use it.
Example of a Component
import { Component } from '@angular/core';
@Component({
selector: 'app-hello', // The tag you’ll use in HTML <app-hello></app-hello>
templateUrl: './hello.component.html', // HTML file for UI
styleUrls: ['./hello.component.css'] // CSS file for styling
})
export class HelloComponent {
title = 'Hello, Angular!';
sayHello() {
alert('Welcome to Angular Components!');
}
}
hello.component.html
<h1>{{ title }}</h1>
<button (click)="sayHello()">Click Me</button>
Key Points about Components:
- Every Angular app has at least one root component (usually
AppComponent
). - Components are organized into modules.
- Components can be reused across the application.
- Data can be passed into a component using
@Input()
and out of a component using@Output()
.
🔹 Ways Components Communicate
1. Parent → Child (using @Input
)
- The parent component can pass data to the child component using an
@Input
property.
child.component.ts
import { Component, Input } from '@angular/core';
@Component({
selector: 'app-child',
template: `<p>Hello, {{ name }}!</p>`
})
export class ChildComponent {
@Input() name!: string; // receives data from parent
}
parent.component.html
<app-child [name]="'Angular Learner'"></app-child>
✅ Output: Hello, Angular Learner!
2. Child → Parent (using @Output
and EventEmitter
)
- The child component can send events/data back to the parent component.
child.component.ts
import { Component, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-child',
template: `<button (click)="sendMessage()">Send to Parent</button>`
})
export class ChildComponent {
@Output() messageEvent = new EventEmitter<string>();
sendMessage() {
this.messageEvent.emit('Hello from Child!');
}
}
parent.component.html
<app-child (messageEvent)="receiveMessage($event)"></app-child>
<p>{{ childMessage }}</p>
parent.component.ts
childMessage = '';
receiveMessage(message: string) {
this.childMessage = message;
}
✅ Output when button clicked: Hello from Child!
3. Sibling Components (through a Shared Service)
- If two components are not directly related (siblings), they can share data using a service.
message.service.ts
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
@Injectable({ providedIn: 'root' })
export class MessageService {
private messageSource = new Subject<string>();
currentMessage$ = this.messageSource.asObservable();
changeMessage(message: string) {
this.messageSource.next(message);
}
}
sender.component.ts
constructor(private messageService: MessageService) {}
sendMessage() {
this.messageService.changeMessage('Message from Sender!');
}
receiver.component.ts
message = '';
constructor(private messageService: MessageService) {}
ngOnInit() {
this.messageService.currentMessage$.subscribe(msg => this.message = msg);
}
✅ The receiver updates whenever the sender sends a new message.
4. Using ViewChild (Parent accesses Child directly)
@ViewChild(ChildComponent) child!: ChildComponent;
ngAfterViewInit() {
console.log(this.child.name); // Access child's property directly
}
📌 Summary
- Parent → Child =
@Input
- Child → Parent =
@Output
+EventEmitter
- Sibling → Sibling = Shared Service
- Direct Access =
@ViewChild