1. Why was a client-side framework like Angular introduced?
Difficulty: EasyType: SubjectiveTopic: Angular vs AngularJS
Client-side frameworks like Angular were introduced to make modern web applications more interactive and maintainable. Earlier, developers had to manually update the DOM using plain JavaScript or jQuery, which became messy for large applications. Angular introduced Single Page Applications (SPAs), data binding, and component-based architecture to keep UI and logic in sync automatically, improve reusability, and organize code effectively.
2. How does an Angular application work?
Difficulty: MediumType: SubjectiveTopic: Angular vs AngularJS
An Angular app is a Single Page Application (SPA) that runs in the browser. It starts with the main.ts file, which bootstraps the AppModule using the bootstrapModule() function. AppModule groups components and services. The AppComponent defines the main view, while index.html loads the root selector <app-root>. Angular uses data binding, directives, and dependency injection to dynamically update the UI without reloading the page.
3. How are Angular expressions different from JavaScript expressions?
Difficulty: MediumType: SubjectiveTopic: Templates
Angular expressions are evaluated in the component’s scope within double curly braces {{ }} and used in templates for data binding. JavaScript expressions run in the global scope. Angular expressions cannot contain loops or assignments and are automatically escaped for security. They are safer and directly bind data to the view, unlike JavaScript which executes logic imperatively in scripts.
4. What are Single Page Applications (SPAs)?
Difficulty: EasyType: SubjectiveTopic: Angular vs AngularJS
Single Page Applications load a single HTML page and dynamically update content as users interact, without full page reloads. This results in faster navigation and smoother user experience. Angular enables SPAs through routing, component reuse, and dynamic DOM updates.
5. What are templates in Angular?
Difficulty: EasyType: SubjectiveTopic: Templates
Templates in Angular define how a component’s view is displayed. They use enhanced HTML with Angular directives and bindings. Templates can be defined inline within the @Component decorator using the 'template' property or in a separate file using 'templateUrl'. They control what appears in the browser and how data from the component is shown.
Example Code
@Component({ selector: 'app-hello', template: `<h1>Hello {{name}}</h1>` })6. What is an AOT compiler in Angular?
Difficulty: MediumType: SubjectiveTopic: Compilation
The Ahead-of-Time (AOT) compiler converts Angular TypeScript and HTML templates into efficient JavaScript before the app runs in the browser. This improves performance, reduces runtime errors, and makes applications load faster compared to Just-in-Time (JIT) compilation, which happens inside the browser.
7. How many types of compilation does Angular provide?
Difficulty: MediumType: SubjectiveTopic: Compilation
Angular supports two types of compilation: JIT (Just-in-Time) and AOT (Ahead-of-Time). JIT compiles the app in the browser at runtime, useful during development. AOT compiles during build time before running, resulting in faster load time and smaller bundles, ideal for production.
8. What is a component in Angular?
Difficulty: MediumType: SubjectiveTopic: Components
A component is the building block of Angular apps. It manages a section of the UI through its logic (TypeScript), view (HTML), and style (CSS). Components are declared with the @Component decorator that defines metadata like selector, template, and styleUrls. Each component controls a part of the screen.
Example Code
@Component({ selector: 'app-header', templateUrl: './header.html' }) export class HeaderComponent { title = 'Header'; }9. Explain the purpose of the @Component decorator in Angular.
Difficulty: EasyType: SubjectiveTopic: Components
The @Component decorator tells Angular that the class is a component. It provides metadata such as the selector (custom HTML tag), template (HTML structure), and styles. It connects the component’s logic to its view, enabling Angular to render and manage the component efficiently.
10. What is a module in Angular?
Difficulty: MediumType: SubjectiveTopic: Modules & NgModule
A module groups related components, directives, pipes, and services into a functional block. It’s defined using the @NgModule decorator and helps organize code for maintainability. Every Angular app has at least one root module (AppModule). Modules can be imported into others for feature segregation and lazy loading.
Example Code
@NgModule({ declarations: [AppComponent], imports: [BrowserModule], bootstrap: [AppComponent] }) export class AppModule {}11. What is the Angular CLI and why is it useful?
Difficulty: EasyType: SubjectiveTopic: Angular CLI
Angular CLI is the official command-line tool. It scaffolds projects, generates code (components, services, pipes), runs a dev server, and builds for production. It enforces best practices and consistent structure, so teams move faster with fewer mistakes. Common commands: `ng new`, `ng serve`, `ng generate`, and `ng build`.
12. Explain the purpose of the @Component decorator.
Difficulty: EasyType: SubjectiveTopic: Components
The `@Component` decorator marks a class as a component and provides metadata: `selector` (custom HTML tag), `template`/`templateUrl` (HTML view), `styleUrls` (scoped styles), and optional providers. Angular reads this to render, style, and inject dependencies into the component.
13. What is a module in Angular and what does @NgModule do?
Difficulty: EasyType: SubjectiveTopic: Modules & NgModule
A module groups building blocks—components, directives, pipes, and services—into a cohesive unit. `@NgModule` declares what belongs to the module, imports other modules it needs, and can bootstrap a root component. Feature modules help split apps for organization and lazy loading.
Example Code
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {}14. What are templates in Angular and how can you define them?
Difficulty: EasyType: SubjectiveTopic: Templates
Templates are enhanced HTML that bind to component data and use directives. Define inline with `template: '...'` for small views, or in a separate file with `templateUrl` for larger ones. Templates can use interpolation, property/event binding, pipes, and structural directives.
Example Code
@Component({ selector: 'app-greet', template: `<h1>Hello {{name}}</h1>` })
export class Greet { name = 'Angular'; }15. What is a directive? Name the main types with examples.
Difficulty: MediumType: SubjectiveTopic: Directives
A directive is a class that adds behavior to elements. Types: (1) Component (a directive with a template). (2) Structural directives change layout by adding/removing elements, e.g., `*ngIf`, `*ngFor`. (3) Attribute directives change look/behavior, e.g., custom hover highlight. Use `@Directive` to build your own.
Example Code
import { Directive, ElementRef, Renderer2, HostListener, Input } from '@angular/core';
@Directive({ selector: '[appHoverBackground]' })
export class HoverBackgroundDirective {
@Input('appHoverBackground') hoverColor?: string;
constructor(private el: ElementRef, private r: Renderer2) {}
@HostListener('mouseenter') onIn(){ this.r.setStyle(this.el.nativeElement, 'backgroundColor', this.hoverColor || 'yellow'); }
@HostListener('mouseleave') onOut(){ this.r.removeStyle(this.el.nativeElement, 'backgroundColor'); }
}16. What is a service and how does dependency injection work in Angular?
Difficulty: MediumType: SubjectiveTopic: Services & DI
A service holds reusable logic like data access or business rules. Angular’s DI framework creates and provides service instances to classes that ask for them. Mark services with `@Injectable({ providedIn: 'root' })` to make a single app-wide instance. Inject them via the constructor.
Example Code
@Injectable({ providedIn: 'root' })
export class DataService {
constructor(private http: HttpClient) {}
fetch(){ return this.http.get('/api/data'); }
}
// In a component
constructor(private data: DataService) {}17. What kinds of data binding does Angular support?
Difficulty: EasyType: SubjectiveTopic: Data Binding — Overview
Angular supports four binding styles: (1) Interpolation `{{ }}` from component → view, (2) Property binding `[prop]` from component → view, (3) Event binding `(event)` from view → component, and (4) Two-way binding `[(ngModel)]` which combines property + event binding for forms.
18. Explain two-way data binding with an example.
Difficulty: EasyType: SubjectiveTopic: Data Binding — Overview
Two-way binding keeps the input and component field in sync. When the user types, the component updates. When the component changes the value, the input updates. Use `[(ngModel)]` from `FormsModule` for template-driven forms.
Example Code
// app.component.html
<input [(ngModel)]="name" placeholder="Your name">
<p>Hello {{name}}</p>
// app.module.ts
imports: [BrowserModule, FormsModule]19. Compare string interpolation and property binding.
Difficulty: EasyType: SubjectiveTopic: Data Binding — Overview
Both are one-way from component to view. Interpolation `{{value}}` converts the result to a string and sets text content or attribute values. Property binding `[prop]="value"` sets a real DOM property. Use property binding when you set non-string values or complex properties (e.g., `[disabled]`, `[value]`, `[src]`).
20. What are Angular lifecycle hooks and when do you use them?
Difficulty: MediumType: SubjectiveTopic: Lifecycle Hooks
Lifecycle hooks let you run logic at key times: `ngOnChanges` (on @Input changes), `ngOnInit` (once after first inputs), `ngDoCheck` (custom change detection), `ngAfterContentInit/Checked` (projected content), `ngAfterViewInit/Checked` (view/child view ready), and `ngOnDestroy` (cleanup). Typical use: fetch data in `ngOnInit`, unsubscribe in `ngOnDestroy`.
Example Code
export class TestComponent implements OnInit, OnDestroy {
sub?: Subscription;
ngOnInit(){ /* start fetching */ }
ngOnDestroy(){ this.sub?.unsubscribe(); }
}21. What is the difference between Angular and AngularJS?
Difficulty: EasyType: SubjectiveTopic: Angular vs AngularJS
Angular (v2+) uses TypeScript, a component-based architecture, AOT/Ivy for speed, and modern tooling. AngularJS (v1.x) used JavaScript, controllers + scopes (MVC), and digest cycles. Angular is faster, mobile-friendly, and better structured for large apps.
22. When would you choose one-way binding vs two-way binding?
Difficulty: EasyType: SubjectiveTopic: Data Binding — Overview
Use one-way binding when the UI only displays data or emits events to the component (simpler and faster). Use two-way binding when you need immediate sync both ways, like form inputs. Keep two-way binding focused on forms to avoid accidental heavy change detection.
23. How do you pass data between parent and child components?
Difficulty: MediumType: SubjectiveTopic: Components
Use `@Input()` on the child to receive data from the parent: `<child [value]="parentValue">`. Use `@Output()` with `EventEmitter` on the child to send events up: `<child (saved)="onSaved($event)">`. For siblings or deep sharing, use a service.
Example Code
// child
@Input() childData!: string;
@Output() childEvent = new EventEmitter<string>();
// parent template
<app-child [childData]="parentData" (childEvent)="handle($event)"></app-child>
24. What is the Angular Router and how does navigation work in an SPA?
Difficulty: MediumType: SubjectiveTopic: Router Basics
The Router maps URLs to components without reloading the page. Define routes in a `Routes` array and render them with `<router-outlet>`. Use `routerLink` for declarative links or `Router.navigate()` in code. This creates fast, app-like navigation.
Example Code
const routes: Routes = [ { path: 'home', component: HomeComponent } ];
// template
<a routerLink="/home">Home</a>
<router-outlet></router-outlet>25. Explain lazy loading and why it matters.
Difficulty: MediumType: SubjectiveTopic: Lazy Loading
Lazy loading defers loading feature modules until a route needs them. This reduces the initial bundle size, speeds up first paint, and improves Core Web Vitals. Configure with `loadChildren` and split large features into dedicated modules.
Example Code
const routes: Routes = [
{ path: 'feature', loadChildren: () => import('./feature/feature.module').then(m => m.FeatureModule) }
];26. What is a pipe in Angular and when would you create a custom one?
Difficulty: EasyType: SubjectiveTopic: Pipes
A pipe transforms values for display in templates (e.g., `date`, `uppercase`, `currency`). Create a custom pipe when you need reusable, pure formatting logic, like masking, unit conversions, or localized labels. Keep pipes pure for performance; use impure only when the output depends on mutable inputs.
Example Code
@Pipe({ name: 'titleCase' })
export class TitleCasePipe implements PipeTransform {
transform(v: string){ return v.replace(/\w\S*/g, s => s[0].toUpperCase() + s.slice(1).toLowerCase()); }
}27. What is Angular Universal and what benefits does it bring?
Difficulty: MediumType: SubjectiveTopic: Angular Universal (SSR)
Angular Universal enables server-side rendering. The server pre-renders HTML, so users see content faster and crawlers index better. Benefits: improved First Contentful Paint, better SEO, and graceful loading on slow devices. The client later hydrates to a full SPA.
28. What are HTTP interceptors and a common use case?
Difficulty: MediumType: SubjectiveTopic: HTTP Interceptors
Interceptors sit between your app and the server. They can read/alter outgoing requests and incoming responses. Common uses: add auth tokens, set headers, log traffic, retry, or handle errors globally. Register them with the `HTTP_INTERCEPTORS` multi provider.
Example Code
@Injectable()
export class TokenInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler){
const token = localStorage.getItem('userToken');
const authReq = token ? req.clone({ setHeaders: { Authorization: `Bearer ${token}` }}) : req;
return next.handle(authReq);
}
}29. What is NgZone and how does it help Angular update the view?
Difficulty: MediumType: SubjectiveTopic: NgZone & Change Detection
NgZone tracks async tasks (timers, XHR, promises). When an async task completes inside Angular’s zone, Angular runs change detection and updates the view. For performance-critical code, you can run work `outsideAngular` and re-enter to update the UI when needed.
30. How do you protect routes so only logged-in users can access them?
Difficulty: MediumType: SubjectiveTopic: Route Guards
Use a `CanActivate` guard. The guard checks auth state; if allowed, it returns `true`. If not, it redirects to `/login` and returns `false`. Combine with an HTTP interceptor to attach tokens and with route data to manage roles.
Example Code
@Injectable({ providedIn: 'root' })
export class AuthGuard implements CanActivate {
constructor(private auth: AuthService, private router: Router) {}
canActivate(): boolean {
if (this.auth.isLoggedIn()) return true;
this.router.navigate(['/login']);
return false;
}
}31. What is a directive in Angular and when would you create one?
Difficulty: EasyType: SubjectiveTopic: Directives
A directive is a class with the @Directive (or @Component) decorator that adds behavior to DOM elements. Use one when multiple components need the same DOM behavior (e.g., hover styles, auto-focus, lazy images). Components are directives with a template; attribute/structural directives change appearance or layout without their own view.
Example Code
import { Directive, ElementRef, HostListener, Renderer2 } from '@angular/core';
@Directive({ selector: '[appHoverBg]' })
export class HoverBgDirective {
constructor(private el: ElementRef, private r: Renderer2) {}
@HostListener('mouseenter') onEnter(){ this.r.setStyle(this.el.nativeElement,'background','#fff3cd'); }
@HostListener('mouseleave') onLeave(){ this.r.removeStyle(this.el.nativeElement,'background'); }
}32. What is a service in Angular and how is it injected?
Difficulty: EasyType: SubjectiveTopic: Services & DI
A service holds reusable business logic or data access and is provided through Angular’s Dependency Injection (DI). Mark the class with @Injectable and provide it (preferably `providedIn: 'root'`). Consumers request it in a constructor or via `inject()` so Angular hands back a singleton instance for that injector scope.
Example Code
@Injectable({ providedIn: 'root' })
export class DataService { constructor(private http: HttpClient) {} getUsers(){ return this.http.get('/api/users'); } }
@Component({...})
export class UsersComponent { constructor(private data: DataService) {} }33. Explain two-way data binding and how you enable it.
Difficulty: EasyType: SubjectiveTopic: Data Binding — Overview
Two-way binding keeps a form control and a component property in sync. Use the banana-in-a-box `[(ngModel)]` for template forms (import FormsModule) or bind FormControl in reactive forms. When the user types, the component value updates; when component value changes, the view reflects it instantly.
Example Code
<input [(ngModel)]="name" placeholder="Your name" />
<p>Hello {{ name }}</p>34. Walk me through key Angular lifecycle hooks you actually use.
Difficulty: MediumType: SubjectiveTopic: Lifecycle Hooks
I use `ngOnInit` for one-time setup or initial fetches, `ngOnChanges` when reacting to @Input changes, `ngAfterViewInit` to access @ViewChild DOM or child components, and `ngOnDestroy` to clean subscriptions/timers. For custom detection, `ngDoCheck` is a last resort.
35. How is Angular different from AngularJS?
Difficulty: EasyType: SubjectiveTopic: Angular vs AngularJS
Angular (2+) uses TypeScript, a component-based architecture, RxJS, and AOT/IVY for faster builds. AngularJS (1.x) used scopes, controllers, digest cycles, and plain JS. Angular targets mobile, better performance, and modern tooling; AngularJS relied on watchers and MVC patterns.
36. List the data binding types in Angular with a quick example each.
Difficulty: EasyType: SubjectiveTopic: Data Binding — Overview
Interpolation: `{{title}}` (component ➜ view). Property binding: `[disabled]="isBusy"`. Event binding: `(click)="save()"` (view ➜ component). Two-way: `[(ngModel)]="form.name"` (both ways). These make templates declarative and keep logic in the component.
37. What is string interpolation and how is it different from property binding?
Difficulty: EasyType: SubjectiveTopic: Data Binding — Overview
Interpolation `{{ expr }}` outputs text into the DOM (e.g., inside a `<p>`). Property binding `[prop]="expr"` sets a real DOM property (e.g., `[value]`, `[src]`, `[disabled]`). Interpolation is for text nodes; property binding affects element behavior and attributes.
38. What is an Angular module and what lives in declarations vs imports vs providers?
Difficulty: MediumType: SubjectiveTopic: Modules & NgModule
An NgModule groups building blocks. `declarations` lists components, directives, pipes that belong to the module. `imports` brings in other modules’ exported declarations (e.g., CommonModule, RouterModule). `providers` registers services for DI in that injector. `bootstrap` lists root components (usually only in AppModule).
Example Code
@NgModule({
declarations: [HomeComponent],
imports: [BrowserModule, RouterModule.forRoot([])],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {}39. How does Angular CLI help your workflow?
Difficulty: EasyType: SubjectiveTopic: Angular CLI
`ng new` scaffolds apps with testing and linting. `ng generate` creates components/services with proper wiring. `ng serve` provides live reload dev server. `ng build --configuration production` generates AOT, optimized bundles. It enforces consistent structure and best practices.
40. Explain how Angular Router changes views without reloading the page.
Difficulty: MediumType: SubjectiveTopic: Router Basics
The Router listens to URL changes and renders the matched component inside `<router-outlet>`. You declare `Routes` that map paths to components, and use `routerLink` for navigation. State persists in memory, so the experience feels like a native app.
Example Code
const routes: Routes = [ { path: 'dashboard', component: DashboardComponent } ];
@NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule {}41. How do you lazy load a feature module and why?
Difficulty: MediumType: SubjectiveTopic: Lazy Loading
Lazy loading splits the app into chunks and loads a feature only when its route is visited, improving first paint and TTI. Use `loadChildren` with a dynamic import in your route config; the CLI creates separate bundles automatically.
Example Code
const routes: Routes = [
{ path: 'admin', loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule) }
];42. What are Angular HTTP interceptors and a common use case?
Difficulty: MediumType: SubjectiveTopic: HTTP Interceptors
Interceptors sit between your app and HttpClient, letting you read/modify requests and responses globally. Typical uses: attach auth tokens, log timing, retry on failures, or translate error responses to user-friendly messages.
Example Code
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler){
const token = localStorage.getItem('userToken');
const cloned = token ? req.clone({ setHeaders: { Authorization: `Bearer ${token}` } }) : req;
return next.handle(cloned);
}
}43. When would you use NgZone or runOutsideAngular?
Difficulty: MediumType: SubjectiveTopic: NgZone & Change Detection
Angular’s zone triggers change detection for async tasks. For heavy, non-UI work (timers, large loops, web workers) use `runOutsideAngular` to prevent excessive checks; when finished, call `run` to update the view. This keeps the UI responsive on CPU-intensive operations.
Example Code
constructor(private zone: NgZone){}
startHeavyWork(){
this.zone.runOutsideAngular(() => {
// expensive work
doExpensiveStuff();
this.zone.run(() => this.progress = 100); // re-enter to update UI
});
}44. How do route guards protect Angular routes?
Difficulty: MediumType: SubjectiveTopic: Route Guards
Guards are services that implement interfaces like `CanActivate`, `CanDeactivate`, or `CanLoad`. They decide if a navigation is allowed. For auth, `CanActivate` checks token/session and either returns true or redirects to login. This centralizes access control.
Example Code
@Injectable({ providedIn: 'root' })
export class AuthGuard implements CanActivate {
constructor(private auth: AuthService, private router: Router) {}
canActivate(): boolean {
if (this.auth.isLoggedIn()) return true;
this.router.navigate(['/login']);
return false;
}
}45. How do you pass data from a parent component to a child component?
Difficulty: EasyType: SubjectiveTopic: Components
Use the @Input() decorator on the child to declare an input property, then bind to it from the parent template. This keeps the data flow explicit and one-way into the child.
Example Code
// child.component.ts
@Input() title!: string;
// parent.component.html
<app-child [title]="pageTitle"></app-child>
46. How can a child component send data or events to its parent?
Difficulty: EasyType: SubjectiveTopic: Components
Use @Output() with EventEmitter in the child and listen for that event in the parent template. Emit values from the child when user actions occur.
Example Code
// child
@Output() saved = new EventEmitter<string>();
onSave(){ this.saved.emit(this.name); }
// parent
<app-child (saved)="handleSave($event)"></app-child>47. When would you use @ViewChild and what are the caveats?
Difficulty: MediumType: SubjectiveTopic: Components
@ViewChild gives you a reference to a child component, directive, or element in the same template. Use it for imperative access (focus an input, call a child method). It becomes available after view initialization (ngAfterViewInit). Avoid using it for data flow that can be expressed declaratively via Inputs/Outputs.
Example Code
@ViewChild('inp') inp!: ElementRef<HTMLInputElement>;
ngAfterViewInit(){ this.inp.nativeElement.focus(); }48. Explain lazy loading in Angular and how to configure it.
Difficulty: MediumType: SubjectiveTopic: Lazy Loading
Lazy loading splits the app into feature bundles that load on demand, reducing initial bundle size and improving startup. Configure routes with loadChildren and place feature routes in the feature module’s routing file.
Example Code
// app-routing.module.ts
const routes: Routes = [
{ path: 'admin', loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule) }
];49. How does the Angular Router enable Single Page Application behavior?
Difficulty: EasyType: SubjectiveTopic: Router Basics
The Router maps URLs to components and swaps them inside <router-outlet> without full page reloads. It supports parameters, guards, resolvers, lazy loading, and browser history integration to deliver SPA navigation.
Example Code
<router-outlet></router-outlet>
50. What are Angular Guards and when would you use CanActivate vs CanLoad?
Difficulty: MediumType: SubjectiveTopic: Route Guards
Guards are services that decide if navigation is allowed. Use CanActivate to allow or block navigation to a route. Use CanLoad to prevent lazy modules from even being downloaded when the user is not authorized.
Example Code
export class AuthGuard implements CanActivate, CanLoad {
constructor(private auth: AuthService, private router: Router) {}
canActivate(){ return this.check(); }
canLoad(){ return this.check(); }
private check(){ if(this.auth.isLoggedIn()) return true; this.router.navigate(['/login']); return false; }
}51. What is a Resolver and why is it useful?
Difficulty: MediumType: SubjectiveTopic: Router Basics
A Resolver fetches data before a route activates so the component receives ready-to-use data and you avoid blank states or flickers. If the resolver fails, you can redirect or show an error route.
Example Code
export class UserResolver implements Resolve<User> {
constructor(private api: Api) {}
resolve(): Observable<User> { return this.api.getUser(); }
}
// route: { path:'profile', component:ProfileCmp, resolve:{ user:UserResolver } }52. What are HTTP interceptors and common use cases?
Difficulty: MediumType: SubjectiveTopic: HTTP Interceptors
Interceptors sit between your app and HttpClient. They can add auth headers, log traffic, retry requests, or centralize error handling. They’re registered as multi providers for HTTP_INTERCEPTORS.
Example Code
export class TokenInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler){
const token = localStorage.getItem('token');
const auth = token ? req.clone({ setHeaders:{ Authorization:`Bearer ${token}` }}) : req;
return next.handle(auth);
}
}53. What is NgZone and how does it relate to change detection?
Difficulty: MediumType: SubjectiveTopic: NgZone & Change Detection
NgZone tracks async tasks (timers, XHR) and triggers change detection when they complete. For performance-critical scenarios, you can run code outside Angular’s zone to avoid unnecessary checks and then re-enter to update the UI.
Example Code
constructor(private zone: NgZone){}
heavy(){ this.zone.runOutsideAngular(() => { expensiveWork(); this.zone.run(() => this.ready = true); }); }54. When should you use the OnPush change detection strategy?
Difficulty: MediumType: SubjectiveTopic: NgZone & Change Detection
Use OnPush when your component inputs are immutable or you update state by replacing object references. It reduces checks to when inputs change, events fire from the component, or an observable emits via async pipe.
Example Code
@Component({ changeDetection: ChangeDetectionStrategy.OnPush })55. What is Angular Universal and what problems does it solve?
Difficulty: MediumType: SubjectiveTopic: Angular Universal (SSR)
Angular Universal pre-renders pages on the server for faster first paint and better SEO. The HTML arrives already rendered; the client then hydrates it, enabling interaction while keeping perceived performance high.
56. What are Standalone Components and how do they simplify apps?
Difficulty: MediumType: SubjectiveTopic: Components
Standalone components remove the need for NgModules. You declare `standalone: true`, import dependencies directly in the component, and wire routes with `loadComponent`. This reduces boilerplate and improves tree-shaking.
Example Code
@Component({ selector:'app-hero', standalone:true, imports:[CommonModule], template:'…' })
export class HeroComponent {}57. What are Typed Forms and why do they matter?
Difficulty: MediumType: SubjectiveTopic: Typed Reactive Forms
Typed Forms add strong typing to FormGroup, FormControl, and FormArray so `form.value` and controls are properly typed. This prevents runtime mistakes (misspelled keys, wrong types) and improves DX and refactoring safety.
Example Code
type Profile = { name: string; age: number };
const form = new FormGroup<Profile>({ name: new FormControl<string>(''), age: new FormControl<number>(0) });58. What is the Signal API and when would you prefer it over services with Subjects?
Difficulty: MediumType: SubjectiveTopic: Components
Signals are reactive primitives that track dependencies and update views automatically without manual change detection. Prefer signals for local component state or simple shared state where you want fine-grained updates with minimal boilerplate. Use RxJS streams when you need rich async composition, multicasting, or complex event pipelines.
59. Explain Angular’s template syntax at a high level.
Difficulty: EasyType: SubjectiveTopic: Templates
Angular templates are HTML enhanced with bindings and directives. You show values with interpolation {{ value }}, bind to element and component inputs with [prop]="expr", listen to events with (event)="handler()", and combine both with two-way binding [(ngModel)]. Structural directives like *ngIf and *ngFor reshape the DOM, while attribute directives change element appearance or behavior.
60. What are structural directives and how do *ngIf and *ngFor work?
Difficulty: EasyType: SubjectiveTopic: Directives
Structural directives change the layout by adding or removing elements. *ngIf inserts the host element only when the condition is truthy. *ngFor repeats the host element for each item in a list. Under the hood, the asterisk is shorthand for using <ng-template> with the directive’s microsyntax.
Example Code
<div *ngIf="loggedIn">Welcome!</div>
<li *ngFor="let user of users; index as i">{{ i }} — {{ user.name }}</li>61. When do you create a custom attribute directive and what does it look like?
Difficulty: EasyType: SubjectiveTopic: Directives
Create an attribute directive when multiple components need the same DOM behavior (e.g., highlight on hover). The directive gets the host element via ElementRef/Renderer2 and responds to HostListener events. Use @Input to pass configuration.
Example Code
@Directive({ selector: '[appHighlight]' })
export class HighlightDirective {
@Input() appHighlight = 'yellow';
constructor(private el: ElementRef, private r: Renderer2) {}
@HostListener('mouseenter') on() { this.r.setStyle(this.el.nativeElement,'background',this.appHighlight); }
@HostListener('mouseleave') off() { this.r.removeStyle(this.el.nativeElement,'background'); }
}62. How do NgClass and NgStyle help with dynamic styling?
Difficulty: EasyType: SubjectiveTopic: Directives
Use [ngClass] to toggle CSS classes based on booleans or expressions, and [ngStyle] to set inline styles dynamically. Both keep templates clean and avoid manual DOM manipulation.
Example Code
<div [ngClass]="{ active: isActive, disabled: !enabled }" [ngStyle]="{ color: danger ? 'red' : 'inherit' }">Row</div>63. Name a few built-in pipes and typical use cases.
Difficulty: EasyType: SubjectiveTopic: Pipes
Common pipes include DatePipe for formatting dates, CurrencyPipe for money, Decimal/PercentPipe for numbers, UpperCase/LowerCase/TitleCase for text, and Slice/Json for arrays and debug. Pipes format data in the view without changing the model.
Example Code
{{ total | currency:'USD' }} · {{ createdAt | date:'medium' }} · {{ name | titlecase }}64. How do you create a custom pipe and when should it be pure?
Difficulty: MediumType: SubjectiveTopic: Pipes
Implement PipeTransform, decorate with @Pipe, and add a transform method. Default pipes are pure—Angular calls them only when input references change, which is fast. Mark a pipe impure (pure:false) only if it depends on mutable data that changes without new references; note it runs every change detection and can hurt performance.
Example Code
@Pipe({ name:'search' })
export class SearchPipe implements PipeTransform {
transform(list: any[], q: string){
if(!q) return list;
const s = q.toLowerCase();
return list.filter(x => x.name.toLowerCase().includes(s));
}
}65. What are parameterized pipes? Give an example.
Difficulty: EasyType: SubjectiveTopic: Pipes
You can pass arguments to pipes using colons. Useful for formats or locales. Example: date:'dd/MM/yyyy' or currency:'EUR':'symbol':'1.2-2'.
Example Code
Birthday: {{ dob | date:'dd/MM/yyyy' }} · Amount: {{ amount | currency:'EUR':'symbol' }}66. Explain Angular’s view encapsulation modes and when to use each.
Difficulty: MediumType: SubjectiveTopic: Components
Emulated (default) scopes styles to the component by adding unique attributes—good balance of isolation and compatibility. ShadowDom uses native shadow root for stronger isolation; great for design systems. None applies styles globally—use sparingly for global themes or legacy overrides.
Example Code
@Component({ selector:'x', template:'…', styles:[`:host{display:block}`], encapsulation: ViewEncapsulation.Emulated })67. Why use Renderer2 instead of direct DOM access?
Difficulty: MediumType: SubjectiveTopic: Directives
Renderer2 abstracts DOM operations so your code works in different platforms (browser, server, web workers) and reduces XSS risks by enforcing safe operations. It also improves testability.
Example Code
constructor(private r: Renderer2, private host: ElementRef){}
ngOnInit(){ this.r.setAttribute(this.host.nativeElement,'role','button'); }68. Summarize common Angular decorators and their purpose.
Difficulty: EasyType: SubjectiveTopic: Components
@Component marks a class as a component. @Directive defines a directive. @Pipe defines a pipe. @NgModule groups declarations and imports. @Input binds a property from parent to child. @Output emits events to the parent. @Injectable makes a class available to DI and can declare providedIn scope.
69. Give a practical use for ngOnChanges, ngOnInit, and ngOnDestroy.
Difficulty: MediumType: SubjectiveTopic: Lifecycle Hooks
Use ngOnChanges to react to @Input changes (e.g., refresh filtered data). Use ngOnInit for one-time setup like fetching initial data or wiring subscriptions. Use ngOnDestroy to clean up: unsubscribe, remove timers, and detach listeners to avoid memory leaks.
Example Code
ngOnDestroy(){ this.sub?.unsubscribe(); clearTimeout(this.tid); }70. How do you handle HTTP errors with RxJS in components and in an interceptor?
Difficulty: MediumType: SubjectiveTopic: Core RxJS Operators
At the component level, pipe the HTTP call through catchError to map or rethrow and show a friendly message. In an interceptor, centralize error handling, optionally retry(), and translate status codes to app errors. Always return an observable.
Example Code
// component
this.api.get().pipe(catchError(err=>{ this.msg='Failed'; return of([]); })).subscribe();
// interceptor
return next.handle(req).pipe(catchError(err=>{ if(err.status===401){ this.auth.logout(); }
return throwError(() => err);
}));71. How do you add SASS/SCSS to an Angular project?
Difficulty: EasyType: SubjectiveTopic: Angular CLI
When creating the project: `ng new app --style=scss`. For an existing app, run `ng config schematics.@schematics/angular:component.styleext scss` and update angular.json styles to point to .scss files. Component styles can directly use .scss files once the builder is configured.
Example Code
// angular.json (excerpt)
"styles": [ "src/styles.scss" ]
72. List a few best practices for clean, fast Angular templates.
Difficulty: MediumType: SubjectiveTopic: Templates
Prefer pure pipes over calling methods in bindings to avoid extra change detections. Use trackBy with *ngFor to prevent re-rendering unchanged items. Keep heavy logic in the component, not the template. Avoid deep async chains—use async pipe or resolvers. Split large templates into smaller presentational components.
73. What is the Angular Router and why do SPAs need it?
Difficulty: EasyType: SubjectiveTopic: Router Basics
The Angular Router lets a Single Page Application (SPA) switch views without full page reloads. It maps URLs to components, updates the address bar, and renders the correct view inside <router-outlet>. This gives users fast, app-like navigation while keeping deep links and browser history working.
74. How do you configure routes and render them in a template?
Difficulty: EasyType: SubjectiveTopic: Router Basics
Define an array of Routes and pass it to RouterModule.forRoot/forChild. Use <router-outlet> where routed components should appear and routerLink for in-app navigation.
Example Code
const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'about', component: AboutComponent }
];
@NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] })
export class AppRoutingModule {}
<!-- template -->
<a routerLink="/about">About</a>
<router-outlet></router-outlet>75. How do you read a route parameter like /users/42?
Difficulty: MediumType: SubjectiveTopic: Router Basics
Declare the param in the route path (e.g., 'users/:id'). In the component, read it using ActivatedRoute. Use snapshot for one-off or params/paramMap observables for reacting to changes when the same component stays mounted.
Example Code
{ path: 'users/:id', component: UserDetailComponent }
constructor(private route: ActivatedRoute) {}
ngOnInit(){
const id = this.route.snapshot.paramMap.get('id');
this.route.paramMap.subscribe(p => this.load(p.get('id')));
}76. When would you use child routes? Show a brief example.
Difficulty: MediumType: SubjectiveTopic: Router Basics
Child routes structure feature areas and nest views. A parent renders a shell with <router-outlet> and the children render inside it (e.g., /settings/profile and /settings/security).
Example Code
{ path: 'settings', component: SettingsShellComponent, children: [
{ path: 'profile', component: ProfileComponent },
{ path: 'security', component: SecurityComponent }
]}77. What’s the difference between routerLink and router.navigate()?
Difficulty: EasyType: SubjectiveTopic: Router Basics
routerLink is a declarative directive used in templates for anchor navigation, which also updates active link styling. router.navigate() is an imperative API used from code (e.g., after a save) to navigate programmatically with extras like query params and state.
Example Code
<a [routerLink]="['/orders', order.id]"></a>
// TS
this.router.navigate(['/orders', id], { queryParams: { tab: 'items' } });78. What are Angular Guards and the common types?
Difficulty: MediumType: SubjectiveTopic: Route Guards
Guards are services that decide if navigation is allowed. CanActivate: enter a route. CanDeactivate: leave a route. CanLoad: load a lazy module. CanMatch: decide if a route matches. Resolve: fetch data before activation.
79. Show how to protect a route so only authenticated users can access it.
Difficulty: MediumType: SubjectiveTopic: Route Guards
Implement CanActivate, check auth state, and return true/false, a UrlTree redirect, or an Observable/Promise of either.
Example Code
@Injectable({ providedIn: 'root' })
export class AuthGuard implements CanActivate {
constructor(private auth: AuthService, private router: Router) {}
canActivate(): boolean | UrlTree {
return this.auth.isLoggedIn() ? true : this.router.parseUrl('/login');
}
}
{ path: 'dashboard', canActivate: [AuthGuard], component: DashboardComponent }80. How do you prevent navigating away when there are unsaved form changes?
Difficulty: MediumType: SubjectiveTopic: Route Guards
Create a CanDeactivate guard that asks the component if it’s safe to leave, optionally showing a confirm dialog. The guarded component exposes a method like hasUnsavedChanges().
Example Code
export interface ExitCheck { hasUnsaved(): boolean; }
@Injectable({ providedIn:'root' })
export class ExitGuard implements CanDeactivate<ExitCheck> {
canDeactivate(cmp: ExitCheck){
return cmp.hasUnsaved() ? confirm('Discard changes?') : true;
}
}
{ path: 'edit/:id', component: EditComponent, canDeactivate:[ExitGuard] }81. Explain lazy loading and provide a route example.
Difficulty: MediumType: SubjectiveTopic: Lazy Loading
Lazy loading splits the app into feature bundles that load on demand, reducing initial bundle size and speeding up startup.
Example Code
{ path: 'admin', loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule) }82. What is preloading in the router and when is it useful?
Difficulty: MediumType: SubjectiveTopic: Lazy Loading
Preloading fetches lazy modules in the background after initial load (e.g., PreloadAllModules) so that later navigations are instant. It balances startup performance with smooth subsequent routing.
Example Code
RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })83. What is a Resolver and why would you use one?
Difficulty: MediumType: SubjectiveTopic: Router Basics
A Resolver fetches data before a route activates so the component has what it needs on first paint (no empty flicker). If the resolver errors, you can redirect or show an error route.
Example Code
@Injectable({ providedIn:'root' })
export class UserResolver implements Resolve<User> {
constructor(private api: Api) {}
resolve(route: ActivatedRouteSnapshot){
return this.api.getUser(route.paramMap.get('id')!);
}
}
{ path:'users/:id', component: UserDetailComponent, resolve:{ user: UserResolver } }84. How do you access RouterState and why might you need it?
Difficulty: MediumType: SubjectiveTopic: Router Basics
RouterState represents the tree of activated routes. You can traverse from the root to read params, data, and URL segments across nested levels—useful for breadcrumbs, analytics, and cross-feature context.
Example Code
constructor(router: Router){
const root = router.routerState.root;
const firstChild = root.firstChild;
// walk the tree to build breadcrumbs
}85. Compare passing data via @Input/@Output with passing data via router extras/state.
Difficulty: MediumType: SubjectiveTopic: Router Basics
Use @Input/@Output for parent↔child communication in a component hierarchy. Use router extras (queryParams, state) for cross-feature navigation or when no direct parent-child relationship exists. Router state is not persisted on hard refresh; URL params are shareable/bookmarkable.
Example Code
// programmatic navigation with state
this.router.navigate(['/checkout'], { state: { cartId } });
// in target component
const cartId = history.state?.cartId;86. How can guards or navigation handle errors and redirects cleanly?
Difficulty: MediumType: SubjectiveTopic: Router Basics
Guards can return a UrlTree to redirect without side effects. Subscribe to router.events and handle NavigationError for global logging. In guards/resolvers, map server errors to a safe UrlTree (e.g., /error) to avoid half-rendered screens.
Example Code
canActivate(): Observable<boolean|UrlTree> {
return this.api.isAllowed().pipe(
map(ok => ok || this.router.createUrlTree(['/forbidden'])),
catchError(() => of(this.router.createUrlTree(['/error'])))
);
}
this.router.events.subscribe(e => {
if(e instanceof NavigationError){ /* report */ }
});87. How does routing interact with Angular Universal for SEO?
Difficulty: MediumType: SubjectiveTopic: Angular Universal (SSR)
With Angular Universal (SSR), the router runs on the server to render the correct route to HTML before sending it to the browser. This improves first paint and lets crawlers index fully rendered pages. Ensure routes don’t rely on browser-only APIs (or guard with isPlatformBrowser).
88. How are Observables different from Promises, and when would you choose each in Angular?
Difficulty: EasyType: SubjectiveTopic: Core RxJS Operators
Observables are streams that can emit many values over time, support cancellation (unsubscribe), and come with a rich operator set (map, switchMap, retry, etc.). Promises emit exactly one value and cannot be cancelled. Use Observables for UI events, HTTP flows that may be retried/cancelled, websockets, and composition. Use Promises for simple, single-result async tasks or interop with APIs that already return Promises.
89. Explain map, filter, tap, and finalize with a simple example.
Difficulty: MediumType: SubjectiveTopic: Core RxJS Operators
map transforms values, filter drops values that don’t match a condition, tap is for side-effects like logging without changing the value, and finalize runs once when a stream completes or errors (e.g., to hide a loader).
Example Code
this.loading = true;
this.api.getUsers().pipe(
map(users => users.filter(u => u.active)),
tap(active => console.log('Active:', active.length)),
finalize(() => this.loading = false)
).subscribe({ next: u => this.users = u, error: e => this.error = e });90. When do you use switchMap, mergeMap, concatMap, and exhaustMap?
Difficulty: MediumType: SubjectiveTopic: Core RxJS Operators
switchMap cancels previous inner requests (great for typeahead). mergeMap runs all inner requests in parallel (best throughput). concatMap queues inner requests one-by-one (order guaranteed). exhaustMap ignores new triggers while one inner request is running (good for login/submit buttons to avoid double submit).
Example Code
fromEvent(input, 'input').pipe(
map((e:any) => e.target.value),
debounceTime(300),
distinctUntilChanged(),
switchMap(term => this.api.search(term))
).subscribe(results => this.results = results);
91. Compare forkJoin, combineLatest, withLatestFrom, and zip.
Difficulty: MediumType: SubjectiveTopic: Core RxJS Operators
forkJoin waits for all observables to complete and emits one array (use for multi-HTTP fetch). combineLatest emits whenever any source emits, using the latest values of each (live combination). withLatestFrom samples another stream’s latest value when the source emits. zip pairs emissions by index and emits tuples.
Example Code
forkJoin({ user: this.api.user(id), posts: this.api.posts(id) })
.subscribe(({user, posts}) => { this.user = user; this.posts = posts; });92. How do you handle errors in HTTP streams and add retry with backoff?
Difficulty: MediumType: SubjectiveTopic: Core RxJS Operators
Use catchError to map an error to a safe value or rethrow. For transient errors (like 5xx), use retryWhen + delay/backoff. Always surface user-friendly messages and log technical details.
Example Code
this.api.getData().pipe(
retryWhen(errors => errors.pipe(
scan((acc) => acc + 1, 0),
takeWhile(retryCount => retryCount < 3),
delayWhen(retryCount => timer(2 ** retryCount * 500))
)),
catchError(err => {
this.toast('Could not load data');
return of([]);
})
).subscribe(data => this.items = data);93. Show a standard takeUntil pattern to cancel streams on component destroy.
Difficulty: MediumType: SubjectiveTopic: Core RxJS Operators
Create a private destroy$ subject, pipe takeUntil(this.destroy$) on long-lived streams, and next/complete it in ngOnDestroy. This prevents memory leaks and cancels active HTTP or interval streams.
Example Code
private destroy$ = new Subject<void>();
ngOnInit(){
this.api.poll().pipe(takeUntil(this.destroy$)).subscribe();
}
ngOnDestroy(){
this.destroy$.next();
this.destroy$.complete();
}94. Differentiate Subject, BehaviorSubject, ReplaySubject, and AsyncSubject with use cases.
Difficulty: MediumType: SubjectiveTopic: Core RxJS Operators
Subject: multicast without initial value (events). BehaviorSubject: stores last value (state). ReplaySubject: replays N values to new subscribers (audit logs). AsyncSubject: emits last value on completion (one-time results).
95. How do you attach an auth token to all requests and refresh it on 401?
Difficulty: MediumType: SubjectiveTopic: HTTP Interceptors
In an interceptor, clone requests with Authorization header from storage. On 401, queue requests and refresh the token once; replay queued requests with the new token. Prevent refresh loops and ensure thread-safety with a shared subject/flag.
Example Code
intercept(req: HttpRequest<any>, next: HttpHandler){
const token = this.auth.token();
const authReq = token ? req.clone({ setHeaders: { Authorization: `Bearer ${token}` }}) : req;
return next.handle(authReq).pipe(catchError(err => this.auth.handle401(err, authReq, next)));
}96. How do valueChanges and statusChanges help reactive forms logic?
Difficulty: EasyType: SubjectiveTopic: Typed Reactive Forms
Both are observables: valueChanges emits when control values change; statusChanges emits when validation status updates. Combine with operators (debounceTime, distinctUntilChanged) to implement live validation, search, or autosave.
97. Show how to read route params and query params reactively.
Difficulty: MediumType: SubjectiveTopic: Router Basics
Use ActivatedRoute.paramMap and queryParamMap as Observables; combineLatest or switchMap them into service calls to react to navigation changes.
Example Code
combineLatest([
this.route.paramMap.pipe(map(p => p.get('id'))),
this.route.queryParamMap.pipe(map(q => q.get('tab')))
]).pipe(
switchMap(([id, tab]) => this.api.load(id!, tab))
).subscribe(vm => this.vm = vm);98. How do you use WebSockets with RxJS in Angular?
Difficulty: MediumType: SubjectiveTopic: WebSockets
Use RxJS webSocket() to create a bidirectional stream. Manage reconnect with retryWhen/backoff. Remember to complete the socket on destroy to close the connection.
Example Code
const socket$ = webSocket('wss://example.com/stream');
socket$.pipe(retryWhen(err$ => err$.pipe(delay(2000)))).subscribe(msg => this.onMsg(msg));99. How do you connect RxJS streams with Signals?
Difficulty: MediumType: SubjectiveTopic: Components
Use toSignal(observable) to expose stream values to templates as signals, and use fromSignal(signal) if you need an observable source. This allows mixing fine-grained reactivity with async streams.
Example Code
const user$ = this.api.user$; // Observable<User>
readonly userSig = toSignal(user$, { initialValue: null });
// template: {{ userSig()?.name }}100. List practical RxJS/HTTP performance tips for Angular apps.
Difficulty: MediumType: SubjectiveTopic: NgZone & Change Detection
Debounce fast inputs, cancel stale requests with switchMap, shareReplay stable data, use trackBy in lists, prefer OnPush change detection, chunk large results (pagination or virtual scroll), and cache idempotent responses via interceptors or state.