Theory
Components that need to talk
FestConnect's event LIST (parent) must pass each event's data DOWN to an event CARD (child), and when a user clicks a card, the child must tell the parent UP which event was selected.
This two-way conversation, data down, events up, is component communication, and Angular has a precise pair of tools for it: @Input and @Output. This lesson covers them, plus directives: the special template instructions (*ngFor, *ngIf, ngClass) that repeat, conditionally show, and style elements. If this feels like React's props-down/callbacks-up plus map/conditionals, that recognition is your shortcut.
Theory
@Input down, @Output up
Angular's communication is a matched pair:
- @Input() marks a property that a PARENT can pass data INTO: data flows DOWN, exactly like React props.
@Input() event: Event; - @Output() with an EventEmitter lets a CHILD send an event UP to its parent. The child does
this.selected.emit(this.event), and the parent listens with(selected)="onSelect($event)"
So the rule is symmetrical: @Input for data down, @Output for events up. The child never reaches into the parent; it EMITS, and the parent decides what to do. This one-way-each-direction flow keeps data predictable, the same discipline React enforces with props and callbacks.
Practical
Parent-child communication
// CHILD component: receives data via @Input, emits up via @Output
import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-event-card',
template: `
<div (click)="select()">{{ event.name }}</div>
`
})
export class EventCardComponent {
@Input() event: any; // data DOWN from parent
@Output() chosen = new EventEmitter<any>(); // event UP to parent
select() {
this.chosen.emit(this.event); // notify the parent
}
}
// PARENT template uses it: passes data in, listens for the event out
// <app-event-card [event]="ev" (chosen)="onChosen($event)"></app-event-card>
Theory
Directives: structural vs attribute
Directives are instructions you put in templates. Two kinds:
Structural directives change the DOM STRUCTURE (add or remove elements), and are prefixed with *:
*ngIf="seats > 0": render the element ONLY if the condition is true*ngFor="let ev of events": REPEAT the element for each item in a list*ngSwitch: choose among several cases
Attribute directives change an element's APPEARANCE or behaviour WITHOUT adding/removing it:
[ngClass]="{ soldout: seats === 0 }": add/remove a CSS class conditionally[ngStyle]="{ color: seats > 0 ? 'green' : 'red' }": set inline styles
The distinction: structural (*) changes WHAT elements exist; attribute changes how existing ones LOOK.
Quiz
In Angular, how does a CHILD component send data or an event UP to its PARENT?
- With @Input()
- With @Output() and an EventEmitter: the child emits, and the parent listens with (event)="handler($event)"
- By directly modifying the parent's properties
- It cannot; data only flows down
Show the answer
With @Output() and an EventEmitter: the child emits, and the parent listens with (event)="handler($event)"
A child sends events UP using @Output() with an EventEmitter: it declares @Output() chosen = new EventEmitter(), calls this.chosen.emit(value) when something happens, and the parent binds to it in the template with (chosen)="onChosen($event)". @Input() (option A) is the OPPOSITE direction: data flowing DOWN from parent to child. Option C violates Angular's design: a child never reaches into its parent directly; it emits and lets the parent respond (keeping data flow predictable). Option D is half-right about @Input but ignores @Output, which exists precisely to send events up. The pair: @Input down, @Output up: mirrors React's props-down, callbacks-up.
Think first
Match Angular directives to React patterns
In React (Unit 2) you used {items.map(...)} for lists and {cond && <X/>} for conditionals. What are the Angular equivalents, and what does this tell you? Then tap.
Show the answer
React's {items.map(item => <X/>)} for rendering a LIST is Angular's ngFor="let item of items". React's {condition && <X/>} (or a ternary) for CONDITIONAL rendering is Angular's ngIf="condition". And React's className/style logic maps to Angular's [ngClass] and [ngStyle]. The tell: both frameworks solve the SAME three template problems, repeat a list, show something conditionally, style conditionally, just with different syntax (JavaScript expressions in JSX vs directives in Angular templates). So learning Angular's directives is mostly learning new NAMES for patterns you already own from React. This is why the second framework is faster to learn than the first: the CONCEPTS transfer, only the spelling changes.
Watch out
Communication and directive traps
Wrong direction: @Input is DOWN (parent to child), @Output/EventEmitter is UP (child to parent); do not swap.
*Forgetting the on structural directives*: it is ngIf and *ngFor (the star matters); [ngClass]/[ngStyle] use brackets, not stars.
Child modifying the parent directly: emit an event instead; keep data flow one-directional.
Missing 'let' in ngFor: it is ngFor="let ev of events", not ngFor="ev of events".
Confusing structural and attribute: structural (*) add/remove elements; attribute (ngClass/ngStyle) restyle existing ones.
Theory
Directives use; now custom ones and binding
You can wire components together and use Angular's built-in directives to shape templates. Next: CUSTOM directives (writing your own) and the full picture of DATA BINDING, interpolation, property binding, event binding, and the famous TWO-WAY binding with ngModel that keeps a form field and a variable in perfect sync. Binding is how Angular templates and TypeScript talk to each other.
Summary
Key takeaways
- Component communication: @Input() passes data DOWN (parent to child, like props); @Output() with EventEmitter sends events UP (child to parent).
- The child emits (this.event.emit(value)); the parent listens with (event)="handler($event)".
- Directives are template instructions; two kinds: structural and attribute.
- Structural directives (prefixed ) change DOM structure: ngIf (conditional), ngFor='let x of list' (repeat), ngSwitch.
- Attribute directives change appearance without adding/removing elements: ngClass (classes), ngStyle (inline styles).
- These map to React: ngFor=map, ngIf=conditional, ngClass/ngStyle=className/style.
- Memory hook: @Input down, @Output up; star directives add/remove, attribute directives restyle.