What are the best Angular developer interview questions?
The best Angular interview questions cover four areas: component architecture and lifecycle hooks (how ngOnInit, ngOnChanges, and dependency injection actually work together), RxJS and state management (operator selection, subscription cleanup, when to reach for NgRx versus signals), change detection and performance (default versus OnPush, zone.js behavior, trackBy usage), and a live coding segment with a practical component-building task. Behavioral questions about async collaboration matter especially for nearshore roles.
Always include at least one live coding segment, not just verbal questions
Avoid trivia questions about Angular version history unrelated to daily component work
For nearshore candidates, assess written English separately from spoken fluency
Great Angular developer interview questions are the difference between a hire who ships and a hire who stalls. The framework has gone through major shifts. NgModules gave way to standalone components. RxJS-heavy state gave way to signals. Candidates who learned Angular at different points bring genuinely different mental models to the same interview. A poor process produces one of two bad outcomes. You hire someone who cannot maintain a real component tree. Or you reject a genuinely strong developer because your questions rewarded trivia instead of judgment.
This guide gives you a complete set of Angular developer interview questions with sample strong and weak answers, plus a scoring rubric you can hand to any engineer on your team to run a consistent, high-signal process. The questions are calibrated for mid-level and senior Angular roles. For junior roles, skip the performance-diagnosis questions and focus on fundamentals, lifecycle hooks, and coding.
Section 1: Component Architecture & Lifecycle Hooks
Angular’s component model is opinionated, and candidates who have only skimmed the docs tend to reach for the constructor when they mean ngOnInit, or misuse ngOnChanges without understanding when it actually fires. These questions separate candidates who understand the component lifecycle from those who have only copied boilerplate.
Q1 • Mid-Level
“What is the difference between the constructor and ngOnInit in an Angular component? Why does it matter?”
Strong answer: The constructor is a plain TypeScript class constructor, called when Angular instantiates the component class, and its main job is dependency injection: receiving injected services as parameters. At that point, Angular has not yet set the component’s input properties. ngOnInit fires after Angular has set the initial input bindings, so any logic that depends on @Input() values, or that needs to kick off an HTTP call using those inputs, belongs in ngOnInit rather than the constructor. A candidate who explains this ordering, and who mentions avoiding heavy logic or async calls in the constructor, is demonstrating real production experience rather than tutorial-level knowledge.
Mid-Level
Q2 • Mid-Level
“Explain Angular’s hierarchical dependency injection. What is the difference between providedIn: ‘root’ and providing a service at the component level?”
Strong answer: Angular’s injector forms a tree that mirrors the component tree. A service registered with providedIn: ‘root’ is a singleton shared across the entire application. Providing the same service in a component’s providers array creates a new instance scoped to that component and its children, which shadows the root instance. This pattern is used deliberately when each instance of a component (for example, a reusable form or wizard component) needs its own isolated state rather than sharing state app-wide. A weak answer treats dependency injection as “Angular’s way of importing things” without understanding the scoping implications, which leads to real bugs like unexpectedly shared state between component instances.
Mid-Level
Q3 • Senior
“You see ExpressionChangedAfterItHasBeenCheckedError in the console during development. What is happening and how do you fix it?”
Strong answer: This error fires because Angular’s change detection runs the check cycle twice in development mode, and a bound value changed between the two passes, meaning a value was mutated after it was already read and rendered in the same cycle. Common causes: setting a property in ngAfterViewInit that affects the parent’s template, or a child component modifying an @Input() derived value during its own change detection pass. Fixes include moving the state change earlier in the lifecycle (ngOnInit instead of ngAfterViewInit), wrapping the update in a setTimeout or Promise.resolve().then() to push it to the next cycle, or calling ChangeDetectorRef.detectChanges() explicitly. A senior candidate will also mention that this is a symptom of a deeper architectural issue: state flowing in a direction the framework doesn’t expect, and the real fix is usually restructuring the data flow rather than papering over it with detectChanges().
Senior
Q4 • Mid-Level
“What are standalone components and how do they change how you structure an Angular application compared to NgModules?”
Strong answer: Standalone components declare their own dependencies directly in the @Component decorator’s imports array instead of relying on an enclosing NgModule to provide directives, pipes, and other components. This removes a layer of indirection: you can open a component file and see exactly what it depends on without hunting through a module declaration. It also simplifies lazy loading, since routes can point directly at a standalone component instead of a module. A strong candidate will note that standalone components are now the default scaffold in new Angular projects, and that migrating an existing NgModule-based app is usually done incrementally rather than as a single rewrite.
Mid-Level
Section 2: RxJS, Observables & State Management
RxJS is where most Angular interviews reveal real experience gaps. Candidates who have only used the HttpClient with a basic subscribe() call have not encountered the problems that operator selection and subscription management solve. These questions probe whether a candidate understands reactive data flow or is just pattern-matching syntax.
Q5 • Mid-Level
“What is the difference between switchMap, mergeMap, and concatMap? Give a real use case for each.”
Strong answer: All three flatten an inner observable, but they differ in how they handle overlapping emissions. switchMap cancels the previous inner observable when a new source value arrives, which makes it correct for a search-as-you-type box where only the latest request result matters. mergeMap runs all inner observables concurrently without cancellation, appropriate when you need to fire off several independent requests and do not care about ordering, such as uploading multiple files in parallel. concatMap queues inner observables and runs them strictly in order, one at a time, which matters when request order affects correctness, such as a sequence of dependent write operations. Using switchMap on a save-button click is a classic mistake since it can cancel an in-flight save if the user clicks twice.
Mid-Level
Q6 • Senior
“Your Angular app is slowly consuming more memory the longer a user stays on a page. What would you investigate first?”
Strong answer: This is the signature symptom of unsubscribed observables. Every manual .subscribe() call inside a component creates a subscription that stays alive until explicitly torn down, and if that teardown does not happen in ngOnDestroy, the subscription (and anything it references) leaks. I would first audit the component for manual subscriptions that are not using the async pipe, then check whether long-lived observables like a WebSocket stream, a setInterval-based observable, or a route param subscription are missing a takeUntil, takeUntilDestroyed, or unsubscribe pattern. My default recommendation is to prefer the async pipe wherever possible since Angular handles the subscription lifecycle automatically, and to use takeUntilDestroyed() for the cases where a manual subscription is unavoidable.
Senior
Q7 • Mid-Level
“When would you reach for NgRx versus a simple service with a BehaviorSubject versus Angular Signals for state management?”
Strong answer: A service with a BehaviorSubject is enough for most feature-level state: a handful of related values that a few components need to read and update, with no complex cross-cutting logic. NgRx earns its overhead when the application has state that many unrelated features touch, when you need time-travel debugging or a strict audit trail of state changes, or when a large team needs the enforced unidirectional data flow to avoid stepping on each other. Signals are the newer, lighter-weight primitive for local and shared reactive state with automatic, fine-grained change detection, and for many new applications they now replace what used to require a BehaviorSubject-based service. A strong candidate explains this as a tradeoff based on team size and state complexity rather than treating NgRx as the default choice for every project.
Mid-Level
Skip the sourcing. Get pre-screened Angular candidates.
Kore BPO delivers pre-vetted nearshore Angular developers from Latin America ready for your technical interview.
Get Candidates
Section 3: Change Detection, Performance & TypeScript
Change detection is Angular’s core performance mechanism, and how a candidate reasons about it tells you whether they can debug a sluggish production application or only know how to build a demo that runs fine with ten rows of test data. TypeScript fluency shows up alongside this, since typed component inputs and typed state are what keep a large Angular codebase maintainable.
Q8 • Mid-Level
“What is the difference between the default change detection strategy and OnPush? When would you use OnPush?”
Strong answer: With the default strategy, Angular checks a component on every change detection cycle, triggered by any browser event, timer, or HTTP response anywhere in the app, which is thorough but expensive at scale. OnPush tells Angular to only re-check the component when an @Input() reference changes, an event originates from within the component, or an observable bound with the async pipe emits. This means OnPush requires immutable data patterns: mutating an object in place and expecting a re-render will silently fail, since the reference did not change. I use OnPush by default on presentational components that receive data via inputs, and I am careful to pair it with immutable update patterns throughout the component tree that feeds it.
Mid-Level
Q9 • Senior
“A list page with 2,000 rows becomes noticeably laggy when the user types in a filter box. How do you diagnose and fix it?”
Strong answer: I would first check the Angular DevTools profiler to see how many components are being checked per keystroke and how long each cycle takes. The most common cause at this scale is *ngFor rendering without a trackBy function, which forces Angular to destroy and recreate every DOM node on each update instead of reusing existing ones. I would add a trackBy function keyed on a stable ID. Second, I would check whether the filter input triggers change detection on every keystroke without debouncing; adding a debounceTime operator on the filter’s valueChanges observable reduces the number of cycles significantly. Third, I would verify the row components use OnPush so unrelated re-renders in the parent do not cascade into 2,000 unnecessary checks. If the list is still slow after these fixes, virtual scrolling with the CDK’s virtual scroll viewport is the next step so only visible rows render at all.
Senior
Q10 • Mid-Level
“How do you use TypeScript generics and utility types to keep an Angular service’s return types strict and maintainable?”
Strong answer: I type the HttpClient calls explicitly rather than letting them infer as any, using an interface for the API response shape. For a generic data service that fetches different entity types, I write a generic method like fetchById<T>(endpoint: string, id: string): Observable<T> so callers get correct typing without duplicating the method per entity. Utility types like Partial for update payloads, Pick and Omit for shaping DTOs from a larger model, and Readonly for state that should not be mutated outside the store all show up in a well-typed Angular codebase. A weak candidate uses any as an escape hatch whenever a type gets complicated, which defeats the purpose of TypeScript and tends to hide real bugs until runtime.
Mid-Level
Section 4: Live Coding Assessment
The live coding segment is the highest-signal part of the Angular interview. It reveals how candidates structure a component, how they handle asynchronous data and error states, and whether they write production-quality code or tutorial-quality code. The right problem is practical, scoped to 30 to 45 minutes, and tests real day-to-day Angular skills.
Recommended Coding Problem
Filterable data list component.
Ask the candidate to build a standalone component that: (1) fetches a list of items from a mocked HttpClient service you provide, (2) exposes a text input that filters the list client-side as the user types, with debouncing, (3) handles a loading state and an error state if the fetch fails, and (4) renders the list using OnPush change detection with a correct trackBy function. Provide the mocked service so the candidate is not writing data access logic from scratch.
What to evaluate: Look for correct use of the async pipe or a manually managed subscription with cleanup, debounceTime and distinctUntilChanged on the filter input, a trackBy function keyed on item ID, and a template that visibly handles loading and error states rather than assuming the happy path. The best candidates also explain why they chose OnPush and how it interacts with the data flow they built.
What Good Code Looks Like
A strong candidate reaches for reactive forms or a typed FormControl for the filter input rather than manual two-way binding with ngModel plus a change handler, wires the input’s valueChanges through debounceTime and distinctUntilChanged, and keeps the component’s template free of business logic by pushing filtering into a computed signal or a piped observable. They will not leave console.log statements in the final code and will name variables so the intent is clear without comments. They may mention that in a real codebase, the HTTP call would live in an injectable service rather than directly in the component. All of these observations are good signals to record on the scoring rubric.
Red Flags in Live Coding
Watch for: subscribing manually without ever unsubscribing (suggests unfamiliarity with the memory leak problem), filtering the list inside the template with a method call instead of a piped observable or computed signal (recalculates on every change detection cycle and hurts performance), missing loading and error states entirely (suggests only building demo-quality code), and inability to explain why trackBy matters when asked a follow-up question.
Section 5: Behavioral Questions for Nearshore Roles
For nearshore placements specifically, behavioral questions assess two things that technical questions cannot: how the candidate communicates complex technical situations in written English, and how they handle the collaboration challenges inherent in distributed team work. These questions are not soft or optional. Poor scores on this section predict friction and integration problems even for technically excellent candidates.
Behavioral Q1
“Tell me about a time a component you built caused a bug that reached production. What happened and what did you do?”
What to listen for: Candidates with production experience will have a specific story with detail: what the bug was, how it was caught, and what they changed afterward. The quality of the answer reveals ownership (did they say “my component” or “the team’s component”), whether they describe a real debugging process rather than a vague fix, and their attitude toward the mistake. Strong candidates describe what they learned and changed, such as adding a test or a code review checklist item. Red flag: a candidate with 3+ years of production experience who claims they have never shipped a bug. That is not a good sign; it suggests either limited real ownership or lack of honesty.
Behavioral Q2
“How do you handle code review feedback that you disagree with?”
What to listen for: Candidates should describe a process that involves understanding the reviewer’s reasoning first, asking clarifying questions, and then either being convinced or articulating their own perspective with evidence. Strong candidates treat code review as a technical discussion, not a judgment of their skill. Weak candidates describe either capitulating to avoid conflict or doubling down on their approach without genuine engagement. For nearshore roles, the ability to articulate technical disagreement clearly in writing, since asynchronous code review is the default mode of collaboration, is particularly important.
Behavioral Q3
“Describe how you would keep your US-based team informed about a feature you are building over a one-week sprint with minimal live meetings.”
What to listen for: This question reveals async communication discipline, the core competency for nearshore collaboration. Strong answers describe daily written status updates with specific progress, blockers, and next steps, plus opening a draft pull request early for visibility rather than waiting until the feature is complete. They may mention using short recorded video walkthroughs for complex UI or state changes that are hard to describe in text alone. Weak answers describe waiting until the PR is finished to share anything, or relying entirely on standup calls for communication. The best candidates proactively surface blockers before they become delays rather than waiting to be asked.
Section 6: Scoring Framework for Angular Developer Interview Questions
Consistent scoring requires a structured rubric. Use this framework across all interviews for the same role. This keeps every candidate evaluated on the same criteria, regardless of which team member runs the interview.
| Category | Weight | Excellent (4) | Acceptable (2-3) | Poor (0-1) |
| Component Architecture & DI | 25% | Explains lifecycle ordering, injector hierarchy, standalone patterns clearly | Knows basic component structure, weak on DI scoping | Cannot explain lifecycle hooks or DI basics |
| RxJS & State Management | 25% | Correct operator selection, subscription cleanup, state tradeoffs | Uses RxJS functionally, limited depth on operator choice | Cannot explain subscription leaks or operator differences |
| Change Detection & Performance | 20% | Diagnoses OnPush, trackBy, and rendering performance issues confidently | Knows OnPush exists, limited debugging depth | Cannot explain change detection strategies |
| Live Coding | 20% | Clean component code, handles loading/error states, explains choices | Working component with gaps in state handling or cleanup | Cannot complete task or missing critical functionality |
| Communication | 10% | Clear, concise, asks good clarifying questions | Understandable but verbose or occasional confusion | Unclear explanations, does not ask questions |
Score each category independently on a 1 to 4 scale, multiply by the weight, and sum for a total score out of 4. A score of 3.2 or above is a strong hire recommendation. Between 2.5 and 3.2 is conditional, depending on which category the weakness is in. Below 2.5 is a pass for a mid-level or senior role.
The biggest interview mistake we see clients make is asking Angular version-history trivia and not enough practical questions about state flow and change detection. Angular is a production framework with real performance tradeoffs. The interview should feel like a production problem, not a pop quiz.
Frequently Asked Questions
How long should an Angular technical interview be?
90 to 120 minutes total split across two sessions works best. Session 1 (60 minutes): concept questions and live coding. Session 2 (45 minutes): performance and architecture discussion for senior roles, plus behavioral questions for all levels. Running everything in a single long session creates fatigue that makes both the candidate and the interviewer perform worse. Splitting sessions also lets you decide after session 1 whether session 2 is worth scheduling.
Should I ask about AngularJS (Angular 1.x) in a modern Angular interview?
Generally no, unless the role specifically involves maintaining a legacy AngularJS codebase. AngularJS and modern Angular (2 and above) share a name but very little architecture. Asking about AngularJS scope and controllers tests knowledge of a framework the candidate will not touch in the role, and penalizes developers who came up entirely on modern Angular, which is most candidates today. Focus questions on the version and patterns your codebase actually uses.
Should I ask about NgRx even if our team does not use it?
Ask about state management reasoning rather than NgRx syntax specifically. What matters is whether the candidate can explain when centralized state helps and when it adds unnecessary overhead, not whether they have memorized NgRx’s action and reducer boilerplate. A candidate who has only used services with BehaviorSubjects but reasons well about state ownership and data flow is often a better hire than one who can recite NgRx syntax without understanding the tradeoffs.
What are the biggest red flags in an Angular developer interview?
The top red flags are: inability to explain the difference between the constructor and ngOnInit (suggests shallow Angular exposure), manually subscribing to observables with no cleanup strategy anywhere in their code, inability to discuss a real production Angular application they have built (suggests tutorial-level experience), describing OnPush change detection as something that “just makes things faster” without understanding the immutability requirement, and reluctance to ask clarifying questions during the coding task.
How do I evaluate English fluency for nearshore Angular candidates?
Evaluate written and spoken English separately. For written fluency, include a take-home exercise that requires a written explanation of a technical decision, such as why they chose a particular RxJS operator. Read it for clarity, structure, and whether the meaning is unambiguous. For spoken fluency, the interview itself is the assessment. Note whether you need to ask for repetition frequently, whether the candidate can explain technical concepts clearly in English under mild pressure, and whether their technical vocabulary is sufficient. Accent is not a concern; clarity and comprehension are.
Should nearshore Angular candidates do the same technical interview as domestic candidates?
Yes, the technical content should be identical. The additional evaluation layer for nearshore candidates is async communication style and time zone overlap expectations, which you assess through the behavioral section rather than by reducing the technical bar. Applying a lower technical standard to nearshore candidates is both unfair to the candidates and counterproductive to your hiring goals. The nearshore advantage is cost and timezone alignment, not a different technical standard.