Angular Cheat Sheet
By Syncfusion®, Inc. · Last updated November 6, 2026
A short reference of the whole course: structure, components, templates, binding, directives, pipes, forms, services, DI, routing, RxJS, HTTP, signals, state, render modes, security, errors and performance.
Angular Application Structure
File or folder Purpose
src/main.tsStarts the app: bootstrapApplication(App, appConfig)
src/index.htmlThe page that contains <app-root>
src/styles.cssGlobal styles
src/app/app.tsThe root component
src/app/app.config.tsApp-wide providers: router, HttpClient, error handler
src/app/app.routes.tsThe list of routes
public/Static files, such as images and favicon.ico
angular.jsonBuild settings, budgets, environments
Command What it does
ng new my-appCreates a project
ng serveStarts the development server on http://localhost:4200
ng buildBuilds the app for production into dist/
ng generate component nameCreates a component (ng g c name)
ng generate service nameCreates a service (ng g s name)
ng generate environmentsCreates the environment files
ng add @angular/ssrAdds server-side rendering
Components
import { Component } from '@angular/core';
@Component({
selector: 'app-product-card', // used as <app-product-card />
imports: [CurrencyPipe], // components, directives, pipes used in the template
templateUrl: './product-card.html',
styleUrl: './product-card.css',
})
export class ProductCard {
name = 'Keyboard';
}
Property Purpose
template / templateUrlInline HTML / HTML file
styles / styleUrl / styleUrlsInline CSS / one CSS file / several CSS files
encapsulationViewEncapsulation.Emulated (default), None, ShadowDom
changeDetectionChangeDetectionStrategy.Default or OnPush
providersComponent-level services
CSS selector Selects
:hostThe component's own element
:host(.selected)The host element when it has a class
:host-context(.dark)The component when a parent has a class
var(--brand-color, #c3002f)A CSS custom property with a default
Templates
Syntax Meaning
{{ name }}Interpolation: show a value
{{ user?.name ?? 'Guest' }}Optional chaining with a default
@if (cond) { } @else if (x) { } @else { }Conditional block
@for (item of items; track item.id) { } @empty { }Loop with tracking and an empty state
@switch (value) { @case ('a') { } @default { } }Switch block
#inputTemplate reference variable
<ng-container>Groups elements without adding an element
<ng-template>Content that is not rendered until it is used
<ng-content />Shows content passed between the component's tags
Data Binding
Binding Syntax Direction
Interpolation {{ value }}Class → template
Property [disabled]="isBusy"Class → element
Attribute [attr.aria-label]="label"Class → HTML attribute
Class [class.active]="isActive"Class → CSS class
Style [style.width.px]="width"Class → CSS style
Event (click)="save()"Element → class
Two-way [(ngModel)]="name"Both directions
Directives and Pipes
Directive Example
ngClass[ngClass]="{ active: isActive, error: hasError }"
ngStyle[ngStyle]="{ color: textColor }"
*ngIf (older)<p *ngIf="loggedIn">Hi</p>
*ngFor (older)<li *ngFor="let o of orders; trackBy: trackById">
Custom attribute directive @Directive({ selector: '[appHighlight]' })
Pipe Example Result
uppercase / lowercase{{ 'hi' | uppercase }}HI
titlecase{{ 'asha rao' | titlecase }}Asha Rao
currency{{ 49.9 | currency }}$49.90
number{{ 3.14159 | number: '1.0-2' }}3.14
percent{{ 0.25 | percent }}25%
date{{ today | date: 'longDate' }}November 6, 2026
slice{{ text | slice: 0:10 }}First 10 characters
json{{ user | json }}The object as JSON text
async{{ data$ | async }}The latest value of an Observable
@Pipe({ name: 'initials' })
export class InitialsPipe implements PipeTransform {
transform(name: string) {
return name.split(' ').map(part => part[0]).join('');
}
}
Event Handling
Event Example
Click (click)="add()"
Key filter (keyup.enter)="search()", (keydown.escape)="close()"
Input text (input)="text = $any($event.target).value"
Change (change)="onSelect($event)"
Form submit (ngSubmit)="save()"
Parameters (click)="remove(item.id)"
Stop the browser action event.preventDefault()
Component Communication
// Child
@Input() product!: Product; // parent → child
@Output() added = new EventEmitter<Product>(); // child → parent
this.added.emit(this.product);
<!-- Parent -->
<app-product-card [product]="selected" (added)="addToCart($event)" />
<!-- Two-way: @Input() size + @Output() sizeChange -->
<app-font-size [(size)]="fontSize" />
Lifecycle Hooks
Hook Runs
constructorWhen the class is created. Inject services here
ngOnChanges(changes)Before ngOnInit, and when an @Input() gets a new value
ngOnInit()Once, after the first inputs are set. Start loading data here
ngDoCheck()On every change detection run
ngAfterContentInit()Once, after projected content is ready
ngAfterContentChecked()After every check of projected content
ngAfterViewInit()Once, after the component's view is ready
ngAfterViewChecked()After every check of the view
ngOnDestroy()Before the component is removed. Clean up here
afterNextRender(fn)Once, in the browser only, after the next render
Template-Driven Forms and Reactive Forms
Point Template-driven Reactive
Import FormsModuleReactiveFormsModule
Defined in The template, with ngModel The class, with FormGroup / FormBuilder
Binding [(ngModel)]="user.name" name="name"[formGroup]="form", formControlName="name"
Best for Small, simple forms Larger forms, dynamic fields, testing
private fb = inject(FormBuilder);
form = this.fb.nonNullable.group({
name: ['', Validators.required],
phones: this.fb.array([this.fb.control('')]),
});
this.form.setValue({ ... }); // all values
this.form.patchValue({ name }); // some values
this.form.reset();
this.form.getRawValue();
Form Validation
Validator Error key
Validators.requiredrequired
Validators.minLength(8) / maxLength(20)minlength / maxlength
Validators.min(0) / max(100)min / max
Validators.emailemail
Validators.pattern(/^[0-9]{6}$/)pattern
State true when
valid / invalidAll rules pass / a rule fails
touched / untouchedThe user left the field / did not
dirty / pristineThe user changed the value / did not
pendingAn async validator is running
// Custom validator: return null when valid
export function noSpaces(control: AbstractControl): ValidationErrors | null {
return String(control.value ?? '').includes(' ') ? { noSpaces: true } : null;
}
control.hasError('minlength');
form.markAllAsTouched(); // show all messages on submit
control.setValidators([...]); control.updateValueAndValidity();
Services
@Injectable({ providedIn: 'root' })
export class CartService {
private readonly _items = signal<string[]>([]);
readonly items = this._items.asReadonly();
add(item: string) {
this._items.update(list => [...list, item]);
}
}
// In a component
private cart = inject(CartService);
Dependency Injection
Provider Gives
CartServiceA new CartService
{ provide: A, useClass: B }A B when A is requested
{ provide: TOKEN, useValue: 20 }A fixed value
{ provide: A, useFactory: () => new A(1) }The result of a function
{ provide: Old, useExisting: New }The same object as New
export const API_URL = new InjectionToken<string>('API_URL');
providers: [{ provide: API_URL, useValue: 'https://api.shop.com' }]
url = inject(API_URL);
analytics = inject(AnalyticsService, { optional: true }); // null if not provided
Where Scope and lifetime
providedIn: 'root'One object for the app, until the app closes
Component providers One object per component, removed with it
Routing
export const routes: Routes = [
{ path: '', redirectTo: 'home', pathMatch: 'full' },
{ path: 'home', component: Home, title: 'Home' },
{ path: 'products/:id', component: ProductDetail },
{ path: 'settings', component: Settings, children: [{ path: 'profile', component: Profile }] },
{ path: 'admin', canActivate: [roleGuard], data: { roles: ['admin'] },
loadChildren: () => import('./admin/admin.routes').then(m => m.ADMIN_ROUTES) },
{ path: 'reports', loadComponent: () => import('./reports/reports').then(m => m.Reports) },
{ path: '**', component: NotFound },
];
provideRouter(routes, withComponentInputBinding())
Task Code
Outlet <router-outlet />
Link <a routerLink="/products" routerLinkActive="active">
Link with parameter [routerLink]="['/products', product.id]"
Query parameters [queryParams]="{ category: 'audio' }"
Navigate in code inject(Router).navigate(['/orders', id])
Read a parameter @Input() id = ''; (with withComponentInputBinding())
RxJS Fundamentals
API Purpose
of(1, 2), from([...]), interval(1000)Create Observables
source$.subscribe({ next, error, complete })Receive values
sub.unsubscribe()Stop receiving
pipe(map(), filter(), tap())Change, filter, side effects
switchMap()Switch to a new request, cancel the old one
catchError() / finalize()Replace an error / run at the end
Subject / BehaviorSubjectSend values / send and store the current value
takeUntilDestroyed()Stop when the component is destroyed
{{ data$ | async }}Subscribe in the template
API Integration
provideHttpClient(withInterceptors([authInterceptor]))
private http = inject(HttpClient);
this.http.get<User[]>('/api/users');
this.http.post<User>('/api/users', newUser);
this.http.put<User>(`/api/users/${user.id}`, user);
this.http.delete<void>(`/api/users/${id}`);
this.http.get('/api/users', { headers: new HttpHeaders({ 'Accept-Language': 'en' }) });
export const authInterceptor: HttpInterceptorFn = (req, next) =>
next(req.clone({ setHeaders: { Authorization: `Bearer ${token}` } }));
Status Meaning
200 / 201 / 204 OK / created / OK with no body
400 Wrong request data
401 / 403 Not logged in / not allowed
404 Not found
500 Server error
0 No connection
Angular Signals
count = signal(0); // writable
count(); // read
count.set(5); // replace
count.update(n => n + 1); // from the current value
items.update(list => [...list, item]); // new list, never push()
double = computed(() => this.count() * 2); // derived, read-only
effect(() => console.log(this.count())); // side effect (in the constructor)
readonly value = this._value.asReadonly(); // read-only view
State Management
Kind Where
Component state A signal in the component
Shared state A store service with private signals, read-only access and methods
RxJS state A private BehaviorSubject with asObservable()
Large apps NgRx: actions → reducer → store → selectors
// NgRx
export const addItem = createAction('[Cart] Add Item', props<{ name: string }>());
export const cartReducer = createReducer(initialState, on(addItem, (s, a) => ({ items: [...s.items, a.name] })));
export const selectCount = createSelector(selectCart, cart => cart.items.length);
store.dispatch(addItem({ name: 'Pen' }));
Render Modes
Mode HTML is created RenderModeBest for
CSR In the browser RenderMode.ClientApps behind a login
SSR On the server, per request RenderMode.ServerPublic pages with changing data
SSG At build time RenderMode.PrerenderDocs, blogs, marketing pages
// app.routes.server.ts
{ path: 'docs/:slug', renderMode: RenderMode.Prerender,
async getPrerenderParams() { return DOCS.map(d => ({ slug: d.slug })); } }
provideClientHydration(withEventReplay()) // app.config.ts
isPlatformBrowser(inject(PLATFORM_ID)) // browser or server?
afterNextRender(() => { /* browser-only code */ });
User Access Control
Concept Summary
Authentication Who is the user? (login)
Authorization What may the user do? (roles)
JWT header.payload.signature, sent as Authorization: Bearer <token>
Expiration The exp claim, in seconds; log out when it passes
export const authGuard: CanActivateFn = () =>
inject(AuthService).isLoggedIn() ? true : inject(Router).createUrlTree(['/login']);
{ path: 'admin', component: Admin, canActivate: [roleGuard], data: { roles: ['admin'] } }
Always check permissions on the server too.
Error Handling
Error Handle with
Missing value ?., ??, @if
A function can throw try { } catch (error) { } finally { }
HTTP request fails catchError() or the error callback
Unknown URL { path: '**', component: NotFound }
Missing provider (NG0201) providedIn: 'root' or providers
Everything else A custom ErrorHandler
@Injectable()
export class AppErrorHandler implements ErrorHandler {
handleError(error: unknown) {
console.error(error); // developers
// log to a server, show a fallback message to users
}
}
providers: [{ provide: ErrorHandler, useClass: AppErrorHandler }]
Look up NG error codes at angular.dev/errors.
Performance Optimization
Technique Code
Lazy loading loadComponent / loadChildren
Budgets "budgets" in angular.json
OnPushchangeDetection: ChangeDetectionStrategy.OnPush
New objects for inputs this.item = { ...this.item, price: 30 }
No heavy methods in templates total = computed(() => ...)
Track list items @for (o of orders; track o.id) / trackBy: trackById
Measure Lighthouse, Performance tab, Angular DevTools Profiler, performance.now()