Components in Angular

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

Leave a Reply