Theory
The class that becomes a screen
In Angular, FestConnect's events page is a component: a TypeScript class that holds the events data and logic, PLUS an HTML template that displays them. The @Component decorator glues the two together.
But a component has a LIFE: it is created, initialised, shown, updated, and eventually destroyed. Angular lets you hook into those moments, and one hook, ngOnInit, is where almost all real work starts (like fetching the events). This lesson covers creating components and their lifecycle hooks, the second being a favourite exam topic and a genuine source of beginner bugs.
Theory
Anatomy of a component
A component is a class decorated with @Component, which links 3 things:
- selector: the custom HTML tag that renders it (
<app-events>) - template (or templateUrl): the HTML view
- styleUrls: its CSS
The CLASS holds the data (a list of events) and methods; the TEMPLATE displays them. You create a component with ng generate component events, which scaffolds all the files and registers it.
So an Angular component is class + template + styles, bundled and named by its selector. Render it by placing its selector tag in another component's template.
Practical
A component with ngOnInit
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-events',
template: '<p>{{ events.length }} events loaded</p>'
})
export class EventsComponent implements OnInit {
events: string[] = [];
// Constructor: keep it LIGHT, mainly for dependency injection.
constructor(private eventService: EventService) {}
// ngOnInit: runs ONCE after the component is initialised.
// THE place for setup like fetching data.
ngOnInit(): void {
this.events = this.eventService.getEvents();
}
}
At a glance
Key lifecycle hooks (in order)
| Hook | When it runs | Use it for |
|---|---|---|
| ngOnChanges | When an @Input property changes | React to changed inputs |
| ngOnInit | Once, after the component is initialised | Initialization: fetch data, set up (most-used) |
| ngAfterViewInit | After the view (template) has rendered | Work needing the rendered DOM |
| ngOnDestroy | Just before the component is destroyed | Cleanup: unsubscribe, clear timers |
Quiz
Where should you put code that fetches a component's data (like loading FestConnect's events)?
- In the constructor, since it runs first
- In ngOnInit, the lifecycle hook that runs once after the component is initialised (the constructor should stay light, mainly for DI)
- In ngOnDestroy
- In the template's HTML
Show the answer
In ngOnInit, the lifecycle hook that runs once after the component is initialised (the constructor should stay light, mainly for DI)
Data fetching and initialization belong in ngOnInit, which Angular calls ONCE after the component is set up and its inputs are available: exactly the right moment. The CONSTRUCTOR (option A) should stay LIGHT and is meant for dependency injection, not heavy work like HTTP calls; doing data fetching there is discouraged (inputs may not be ready, and it complicates testing). ngOnDestroy (option C) is for CLEANUP as the component leaves, the opposite end of life. Option D confuses logic with the view. The convention: constructor for injecting dependencies, ngOnInit for initialization. This mirrors React's useEffect(() => {...}, []) running once on mount.
Think first
ngOnInit and React's useEffect
In React (Unit 2) you fetched events with useEffect(() => {...}, []). Angular fetches them in ngOnInit. How are these two the same idea? Then tap.
Show the answer
They play the SAME role: 'run this setup code ONCE, when the component is ready, after its first render/initialization'. React's useEffect with an empty dependency array [] runs once on mount; Angular's ngOnInit runs once after the component is initialised. Both are the designated home for initialization like fetching data, so that heavy work does not happen during construction/render. The frameworks differ in mechanism (a hook vs a lifecycle method on a class) but agree on the PATTERN: separate 'set up when ready' from the constructor/render. Recognising this equivalence means you already understand Angular's lifecycle from your React knowledge: ngOnInit IS useEffect-on-mount in Angular clothing. Different framework, same lifecycle instinct.
Watch out
Component and lifecycle traps
Heavy work in the constructor: keep it light (DI only); do fetching/setup in ngOnInit.
Forgetting to implement the interface: implements OnInit and add ngOnInit(); a misspelt hook name silently never runs.
No cleanup in ngOnDestroy: unsubscribe from Observables and clear timers there, or you leak.
Expecting the view in ngOnInit: the rendered DOM is guaranteed only by ngAfterViewInit, not ngOnInit.
Selector clashes: each component's selector should be unique.
Theory
Components live; now let them talk
You can create components and run initialization in their lifecycle. But real apps have components that must COMMUNICATE: a parent passing data to a child, a child notifying its parent. The next lesson covers component communication (@Input, @Output, EventEmitter) and Angular's DIRECTIVES (ngIf, ngFor, ngClass), which control how templates render lists and conditions, the Angular equivalents of the React patterns you already know.
Summary
Key takeaways
- A component is a TypeScript class decorated with @Component, linking a selector (custom tag), a template (HTML), and styles.
- Create components with ng generate component name; render one via its selector tag.
- Lifecycle hooks are methods Angular calls at key moments: ngOnChanges, ngOnInit, ngAfterViewInit, ngOnDestroy.
- ngOnInit runs once after initialization: THE place for setup and data fetching.
- Keep the constructor light (mainly dependency injection); do heavy work in ngOnInit.
- ngOnDestroy is for cleanup (unsubscribe, clear timers) before the component is destroyed.
- Memory hook: ngOnInit is Angular's on-mount setup, like React's useEffect(() => {}, []).