Ace Your Interviews 🎯
Browse our collection of interview questions across various technologies.
What is Angular and how does it differ from React?
Angular is a full application framework maintained by Google — it ships with routing, HTTP client, forms module, DI container, animations, and testing utilities. React is a UI rendering library — it only handles the view layer; developers choose their own solutions for everything else. Angular enforces structure through TypeScript and NgModules; React gives flexibility with less convention.
What is TypeScript and why does Angular require it?
TypeScript is a statically-typed superset of JavaScript that compiles to plain JS. Angular uses TypeScript's decorators (@Component, @Injectable, @NgModule) — a TypeScript feature. TypeScript's compile-time type checking catches integration bugs before runtime, which is critical in Angular's large-scale target applications.
What is a Component in Angular?
A TypeScript class decorated with @Component that has a selector (the custom HTML tag), a template (HTML), optional styles (CSS/SCSS), and logic. Components are the UI building blocks — every Angular application is a tree of components starting from AppComponent at the root.
What is Dependency Injection in Angular?
A design pattern where Angular's DI container provides instances of services to components and other services that declare them in their constructor. Services decorated with @Injectable({ providedIn: 'root' }) are singletons — Angular creates one instance and injects the same one everywhere it's needed.
What is an Observable and how is it used in Angular?
An RxJS Observable is a lazy stream that emits values over time. Angular's HttpClient returns Observables for HTTP calls. Components subscribe to receive data. Unlike Promises, Observables can emit multiple values, be cancelled, and transformed with operators like map, filter, and switchMap before subscribing.
What is the difference between *ngIf and *ngFor?
*ngIf is a structural directive that conditionally adds or removes an element from the DOM based on a boolean expression. *ngFor is a structural directive that renders a template for each item in a collection. Both are structural directives — they change the DOM structure, not just appearance.
What is Angular's data binding? Explain all four types.
Interpolation {{ value }} — renders component property in template. Property binding [property]='value' — sets DOM property from component. Event binding (event)='handler()' — listens to DOM events. Two-way binding [(ngModel)]='value' — synchronizes component property with input in both directions (requires FormsModule).
What is the async pipe and why is it preferred?
The async pipe subscribes to an Observable or Promise in the template and automatically unsubscribes when the component is destroyed — preventing memory leaks. It also triggers OnPush change detection when new values emit. Using it eliminates the need to manually subscribe, store subscriptions, and unsubscribe in ngOnDestroy.
What is the Angular CLI and what are its most useful commands?
Angular CLI is a command-line tool for Angular development. Key commands: ng new (create project), ng generate component/service/module/guard/pipe (create files with boilerplate), ng serve (development server with hot reload), ng build --configuration production (optimized production build), ng test (run unit tests).
What is the difference between Template-Driven and Reactive Forms?
Template-Driven forms define form logic in HTML using NgModel — simpler for small forms, hard to test and type-check. Reactive Forms define the form model in TypeScript using FormGroup and FormControl — testable, type-safe, better for complex/dynamic forms. Always use Reactive Forms in production Angular applications.
Explain Angular's change detection and how OnPush improves performance.
Angular's default change detection (Zone.js-based) checks every component in the tree on every async event. OnPush tells Angular to check a component ONLY when its @Input references change or an Observable it subscribes to emits a new value. Applied to list components, OnPush can reduce change detection calls from thousands to dozens per second.
What is an HTTP Interceptor? Write an auth interceptor.
An HTTP Interceptor implements HttpInterceptor and intercepts all outgoing requests and incoming responses. Registered in AppModule providers with { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true }. Auth interceptor: clones the request, adds Authorization: Bearer token header, returns next.handle(authReq). Error interceptor: catchError on the response stream, handles 401 (logout), 403 (redirect), 500 (notify).
What is the difference between canActivate and canLoad route guards?
canActivate fires when a user navigates to a route — it can block navigation but the lazy-loaded module JavaScript is already downloaded. canLoad fires before a lazy-loaded module's bundle is downloaded — it prevents unauthorized users from even downloading the module code. Both should be applied to sensitive lazy-loaded routes.
What is the difference between switchMap, mergeMap, concatMap, and exhaustMap?
switchMap: cancels the previous inner Observable when a new emission arrives — ideal for search. mergeMap: runs all inner Observables concurrently — parallel independent operations. concatMap: queues inner Observables sequentially — ordered operations like serial uploads. exhaustMap: ignores new emissions while an inner Observable is active — prevents duplicate form submissions.
How does lazy loading work in Angular? Why is it important?
Lazy loading uses loadChildren in the router to split the app into chunks. The initial bundle contains only AppModule code. Feature module chunks are downloaded only when the user navigates to that route for the first time. This can reduce initial bundle size by 60–80% for large apps, dramatically improving first-page load time.
What is ViewEncapsulation in Angular?
ViewEncapsulation controls how Angular scopes component CSS. Emulated (default): Angular adds unique attributes to elements and rewrites selectors to scope styles to the component — styles don't leak out or in. None: global CSS — styles affect all components. ShadowDom: uses native browser Shadow DOM for true style isolation.
What is the difference between BehaviorSubject and Subject?
Subject: emits to current subscribers only — new subscribers miss previous emissions. BehaviorSubject: requires an initial value; emits the current value immediately to new subscribers. In Angular, BehaviorSubject is used for shared state (auth user, cart) because new components that subscribe immediately receive the current state, not an empty Observable.
How do you share data between unrelated components in Angular?
Through a shared service with a BehaviorSubject (or Subject for events). The service is a singleton (providedIn: 'root'). Any component can inject the service and subscribe to its Observable or call its methods. This is Angular's pub/sub pattern — the foundation of all cross-component communication that doesn't use @Input/@Output.
What is trackBy in *ngFor and when should you use it?
trackBy provides *ngFor with a function that returns a unique identifier for each item. Without it, Angular destroys and recreates all DOM nodes when the array changes. With trackBy, Angular reuses DOM nodes for items whose identifier hasn't changed and only creates/destroys nodes for genuinely added/removed items. Use it for all dynamic lists, especially with OnPush components.
How do you test an Angular component?
Using TestBed.configureTestingModule to create a testing module with the component and its dependencies (real or mocked). ComponentFixture wraps the component instance and provides detectChanges() to trigger change detection. Inject services with TestBed.inject(), use jasmine.createSpyObj to mock them. HttpClientTestingModule mocks HTTP calls. Assert against the compiled DOM via fixture.nativeElement.
What is NgRx and when should you use it over BehaviorSubject services?
NgRx implements Redux for Angular: single immutable state tree, actions (events), reducers (pure state transitions), selectors (memoized queries), effects (async operations). Use NgRx when: multiple unrelated components need to read and write the same state, mutation sources are complex, you need time-travel debugging with DevTools, or your team needs a strict contract to prevent state bugs. For simpler shared state, BehaviorSubject in services is less boilerplate and equally effective.
What are Angular Signals and how do they differ from RxJS Observables?
Signals (stable in Angular 17+) are synchronous reactive primitives — signal() holds a value, computed() derives a value, effect() reacts to changes. Unlike Observables, Signals are always synchronous, always have a current value, and don't require subscription management. Signals are ideal for component UI state and computed values. RxJS Observables remain superior for async streams, HTTP calls, time-based operators, and complex event composition. Use both.
How do you implement Angular Universal (SSR) and why?
Angular Universal adds server-side rendering using @angular/ssr package. The Express server runs Angular to generate HTML on the server, sends it to the browser, then Angular hydrates the static HTML into a fully interactive app. Reasons: SEO (search bots see real content), faster First Contentful Paint (no blank HTML flash). Key challenge: server-only code (no browser APIs like localStorage — use PLATFORM_ID and isPlatformBrowser to guard them).
How do custom structural directives work?
Structural directives use TemplateRef (the template to stamp) and ViewContainerRef (where to stamp it). *appHasRole directive injects AuthService and the TemplateRef — in ngOnInit, it checks the user's role and either calls viewContainerRef.createEmbeddedView(templateRef) to show it or viewContainerRef.clear() to hide it. The * syntax is sugar for <ng-template [appHasRole]>. Re-evaluating on role changes requires subscribing to auth state.
How would you architect an Angular app for a 30-person engineering team?
Monorepo with Nx. Core/Shared/Features architecture — each team owns a lazy-loaded feature module with its own NgRx slice, routing, services, and components. Shared module for common UI. CoreModule for singletons. Strict eslint with module boundary rules (a feature module cannot import another feature module directly). Shared TypeScript interfaces for API contracts. Storybook for component documentation. CI that runs only affected tests on PRs.
What is Module Federation in Angular and what problem does it solve?
Module Federation (Webpack 5 feature, integrated into Angular with @angular-architects/module-federation) allows multiple independently-deployed Angular applications to share components and services at runtime — each micro-frontend is owned by a different team, deployed on its own schedule, but composed into a single shell application. Solves the problem of 10 teams trying to merge code into one Angular repo before every release.
How do you optimize the initial bundle size of an Angular application?
Lazy-load all feature modules. Use differential loading (Angular CLI default — ES2015 bundle for modern browsers, ES5 for legacy). Tree-shake unused Angular Material components (import only used modules). Audit with ng build --stats-json + webpack-bundle-analyzer. Preload strategy for likely-visited routes. Code-split large libraries (Moment.js → date-fns). Use standalone components (Angular 14+) to eliminate NgModule overhead.
How do you implement role-based access control in Angular end-to-end?
Backend: user has role field, JWT encodes role, route middleware checks it. Angular: JWT decoded on login, role stored in AuthService. RoleGuard reads route.data.roles, compares to auth user's role. Custom *appHasRole structural directive shows/hides UI elements. Never trust frontend RBAC alone — backend must enforce independently. The UI RBAC is UX; the backend RBAC is security.
What is the difference between a pure and impure pipe?
Pure pipe (default): Angular only re-executes the transform() when the input value reference changes. Fast, memoized. Impure pipe: Angular re-executes on every change detection cycle regardless of input change. Required for pipes that depend on mutable data or external state (like a FilterPipe filtering an array that mutates in place). Impure pipes are a performance risk — prefer pure pipes and immutable data patterns.
How do you handle large data tables (100,000 rows) in Angular?
Angular CDK's CdkVirtualScrollViewport with *cdkVirtualFor renders only the rows visible in the viewport — 20 DOM nodes for 100,000 data rows. Pair with server-side pagination for truly large datasets. OnPush on the row component to prevent full-table re-renders on filter changes. Backend indexed queries for sorting and filtering instead of client-side operations on the full dataset.
How do you write an end-to-end test for an Angular application with Cypress?
Install Cypress, configure with ng add @cypress/schematic. Write spec files in cypress/e2e/. cy.visit() navigates to the app URL. cy.get('[data-cy=login-email]').type() interacts with elements (use data-cy attributes, not CSS classes). cy.intercept() mocks API calls with fixture data. cy.get('[data-cy=dashboard]').should('be.visible') asserts outcomes. Run with ng e2e in CI after ng build.