Interview questions · free

Angular Developer interview questions and answers

34 questions Angular Developer interviews in India ask, grouped by the 8 skills they test, with a short model answer for each. Then the HR round every job has. Try each one out loud before you open the answer.

  • 34 questions
  • 8 skills
  • 16 for freshers
  • Updated 30 Oct 2026

First mock interview free: 3 questions, a score and feedback on each · No card needed

Answer out loud first. Read the question, say your answer as you would in the room, then open the model answer and compare. Interviewers ask follow-ups, so learn the reasoning, not the words.

Angular · Core skill

Components, templates and change detection

Components are the heart of every Angular app, so interviews start with binding, communication and lifecycle hooks, then move to change detection, where most performance problems begin.

What are the types of data binding in Angular?Fresher

There are four. Interpolation, with double curly braces, shows a value as text: {{ user.name }}. Property binding, with square brackets, sets an element or component property from the class: [disabled]="isSaving". Event binding, with parentheses, calls a method when something happens: (click)="save()". Two-way binding combines the two, written [(ngModel)]="email" for form fields (the "banana in a box"), so the field and the class property stay in sync.

The first three are one-way: data flows from the class to the view, or events flow from the view to the class. Mention that [(x)] works on your own components too, with an x input and an xChange output, or a model() signal in recent versions.

How do a parent and a child component share data in Angular?Fresher

Parent to child, through inputs: the child declares an input, with the @Input() decorator or the newer input() function, which returns a signal, and the parent binds it: [product]="selectedProduct". Child to parent, through outputs: the child declares an output, with @Output() and an EventEmitter or the newer output() function, and emits a value; the parent listens with (added)="onAdded($event)". A parent can also reach a child directly with ViewChild.

For components that aren't parent and child, such as two siblings or a header and a page, share a service that holds the data in a signal or a BehaviorSubject. If you're passing an input down through five levels, that's a sign you need a service.

What is the difference between the constructor and ngOnInit? Name the lifecycle hooks in order.Fresher

The constructor is plain TypeScript: it runs when Angular creates the class, before any inputs are set, so use it only for injecting dependencies. ngOnInit runs once, after Angular has set the inputs for the first time, so it's the place to start loading data that depends on them.

The order is ngOnChanges (each time a bound input changes, and only if there are bound inputs), ngOnInit, ngDoCheck, ngAfterContentInit and ngAfterContentChecked (for projected content), ngAfterViewInit and ngAfterViewChecked (for the component's own view and its children), and finally ngOnDestroy, where you clean up subscriptions, timers and listeners. Forgetting that clean-up is a classic cause of memory leaks.

Your component uses OnPush change detection, and its list doesn't update when a new item is pushed into the array. Why, and how do you fix it?1-6 years

With the default strategy, Angular checks every component after each event, timer or HTTP response that Zone.js reports. With OnPush, it checks a component only when an input gets a new reference, an event is handled inside it, an async pipe in it emits, or a signal its template reads changes. Pushing into the same array keeps the same reference, so Angular sees no change.

The fix is to treat inputs as immutable: replace the array, this.items = [...this.items, newItem]. Alternatively keep the list in a signal and set a new array, use the async pipe, or, as a last resort, call markForCheck() on ChangeDetectorRef. OnPush is worth it in large apps because it skips whole subtrees during checks.

What are standalone components? How would you move an NgModule-based app to them?1-6 years

A standalone component lists its own dependencies, such as other components, directives and pipes, in its imports array instead of being declared in an NgModule. That makes each component self-contained, easy to lazy-load with loadComponent, and removes a lot of module boilerplate. Recent Angular versions create components as standalone by default, and the app starts with bootstrapApplication and providers like provideRouter and provideHttpClient.

To migrate, the Angular CLI has a schematic, ng generate @angular/core:standalone, that converts components, removes modules that are no longer needed and switches the bootstrap, in separate steps. Go feature by feature and run the tests after each step; standalone and NgModule code work together during the move.

Angular · Core skill

RxJS, signals and HTTP

Angular's HTTP, forms and router are built on RxJS, and signals are now central too, so interviewers spend a lot of time on streams, operators and interceptors.

What is the difference between an Observable and a Promise?Fresher

A Promise represents one future value: it starts running as soon as it's created, resolves or rejects once, and can't be cancelled. An Observable is a stream that can emit many values over time, does nothing until someone subscribes (it's lazy), and can be cancelled by unsubscribing, which for an Angular HTTP request aborts the call.

Observables also come with operators like map, filter, debounceTime and switchMap to transform and combine streams, which is why Angular uses them for HttpClient, router events and form valueChanges. An HTTP call emits once and completes, so it behaves much like a Promise, but you can still retry, cancel or combine it. firstValueFrom converts one to a Promise when needed.

What is the difference between Subject, BehaviorSubject and ReplaySubject?Fresher

All three are Observables you can also push values into with next(), and they share each value with all their subscribers. A plain Subject has no memory: a subscriber gets only values emitted after it subscribes. A BehaviorSubject needs a starting value and always holds the current one, so a new subscriber gets the latest value at once, and you can read it with getValue(). A ReplaySubject replays the last n values to new subscribers.

A BehaviorSubject is the usual choice for state in a service, such as the logged-in user or the cart, exposing only asObservable() to components. For one-off events, like "saved", a plain Subject fits. In newer code, signals often replace BehaviorSubject for simple state.

A search box calls the API on every keystroke, and results sometimes come back out of order. How would you fix it with RxJS?1-6 years

Build the stream from the input's valueChanges: debounceTime(300) waits until the user pauses, distinctUntilChanged() skips the call if the text hasn't changed, filter drops terms that are too short, and switchMap calls the API. switchMap is the key: when a new term arrives, it unsubscribes from the previous request, which cancels it, so an old, slow response can never overwrite newer results.

Know the alternatives: mergeMap runs all requests in parallel, returning in any order; concatMap queues them one after another, good for saves that must keep their order; exhaustMap ignores new values while one is running, good for a submit button pressed twice. Put catchError inside the switchMap so one failed request doesn't end the whole stream.

How would you add the login token to every request and handle a 401 response in one place?1-6 years

With an HTTP interceptor. In current Angular it's a function (HttpInterceptorFn) registered with provideHttpClient(withInterceptors([authInterceptor])); older apps use a class implementing HttpInterceptor, registered with HTTP_INTERCEPTORS. Requests are immutable, so the interceptor clones the request, req.clone({ setHeaders: { Authorization: 'Bearer ' + token } }), and passes the clone to next.

For errors, pipe the response through catchError: on a 401, try refreshing the token once and retry, or clear the session and send the user to the login page; rethrow other errors. Add the token only to your own API's URLs, never to third-party calls. Interceptors also suit loading indicators, logging and adding a request id.

When would you use signals instead of RxJS observables in Angular?1-6 years

Signals are for state: a value that always exists and changes, which the template reads directly. signal() holds a value, computed() derives one from other signals and recalculates only when they change, and effect() runs side effects. Angular knows exactly which views read a signal, so it updates just those, and there's nothing to subscribe to or unsubscribe from.

RxJS is still better for events and async work over time: debouncing input, cancelling requests, retrying, combining several streams. The two work together: toSignal turns an observable, such as an HTTP result, into a signal for the template, and toObservable goes the other way. A sensible rule is signals for what the screen shows, RxJS for how the data arrives.

JavaScript · Core skill

TypeScript

Angular is written in TypeScript and every Angular project uses it, so interviewers expect real fluency: generics, narrowing and strict settings, not just adding types to variables.

Why does Angular use TypeScript? What does TypeScript check, and what doesn't it do at runtime?Fresher

TypeScript adds static types to JavaScript, and the compiler checks them when you build: calling a method that doesn't exist, passing a string where a number is expected, or forgetting that a value can be null. Editors use the types for autocomplete and safe renaming, which matters in large Angular codebases with many services and models. Angular also uses them for decorators and for type-checking templates.

But types are removed when the code compiles to JavaScript, so nothing is checked at runtime. If the API returns an id as the string "5" while your interface says number, TypeScript won't notice. Validate outside data when it matters, and don't silence errors with type assertions like as User.

What are generics? Show how you'd use one with an Angular HttpClient call.Fresher

Generics let you write a function, class or interface that works with many types while keeping the type information, through a type parameter such as T. Instead of returning any, the function says it returns whatever type you give it.

HttpClient uses them: this.http.get<Product[]>('/api/products') returns Observable<Product[]>, so the subscriber knows each item's fields. You can write your own too: interface ApiResponse<T> { data: T; total: number }, then http.get<ApiResponse<Product[]>>(url). Remember that the type argument to http.get is only a promise to the compiler: Angular doesn't check that the server's data really matches it.

How would you model a screen's loading, success and error states in TypeScript so the template can't show data that isn't there?1-6 years

Use a discriminated union: type State = { status: 'loading' } | { status: 'success'; data: Order[] } | { status: 'error'; message: string }. Every member has the same status field with a different literal value, and data exists only on the success member. After checking state.status === 'success', TypeScript narrows the type, so state.data is allowed there and an error everywhere else.

This beats three separate fields (loading, data, error), which allow impossible combinations such as loading with an error. In the template, check the status with @if or @switch. In a switch over status in the class, a default case that assigns state to a never variable gives a compile error wherever a newly added status isn't handled.

You're asked to turn on strict mode in an old Angular project, and it shows 600 errors. How do you approach it?1-6 years

strict in tsconfig turns on several checks at once; the most work is usually strictNullChecks (null and undefined must be handled) and strictPropertyInitialization (class fields must be given a value). Angular adds its own, strictTemplates in angularCompilerOptions, which type-checks templates too.

Don't fix 600 errors in one pull request. Turn the flags on one at a time, for example noImplicitAny first, then strictNullChecks, and fix module by module, starting with shared models and services that everything depends on. Prefer real fixes, like handling a missing value or initialising a field, over scattering ! and as everywhere. Keep new code strict with lint rules, and track the error count falling each week.

Angular

Dependency injection, routing and forms

Services, routing and forms are part of every Angular screen, and interviewers use them to see whether you understand how the framework is wired together.

What is dependency injection in Angular? What does providedIn: 'root' mean?Fresher

Dependency injection means a class asks for what it needs and Angular creates and supplies it, instead of the class making its own copies with new. A component asks for a ProductService in its constructor or with inject(ProductService), and Angular's injector provides it. This keeps classes loosely coupled and makes testing easy, since a test can provide a fake service.

providedIn: 'root' registers the service in the application's root injector, so there's one shared instance for the whole app, and it's left out of the bundle if nothing uses it. Listing a service in a component's providers instead gives each instance of that component its own copy, which suits state that belongs to one form or widget.

What is the difference between reactive forms and template-driven forms? Which would you use for a long registration form?Fresher

Template-driven forms are built mostly in the template, with ngModel and attributes like required, and Angular creates the form model behind the scenes. They're quick for simple forms such as a login. Reactive forms are built in the component class with FormGroup, FormControl and FormBuilder, and the template just binds to them. The model is explicit and synchronous, so validation, dynamic fields with FormArray, custom validators and unit tests are much easier.

For a long registration form I'd choose reactive forms: for example, a validator that checks password and confirm-password match, or adding a GSTIN field only when the user picks "Business". Reactive forms are also strictly typed in recent Angular versions.

How would you protect an admin section of an Angular app and load its code only when it's needed?1-6 years

Lazy-load it with the router: { path: 'admin', loadChildren: () => import('./admin/admin.routes').then(m => m.ADMIN_ROUTES) } for a set of routes, or loadComponent for one standalone component. Its code then goes into a separate bundle, downloaded only when someone opens /admin. Protect it with a guard: a functional CanActivateFn, or canMatch, which also stops the code downloading for users who aren't allowed, that uses inject(AuthService) to check the role and returns true, or a UrlTree that redirects to the login page.

Always add that guards are only for user experience: anyone can change frontend code in their browser, so the backend must check permissions on every admin API call.

Reading an answer isn't the same as giving one

In a mock interview you answer new Angular Developer questions out loud or typed, and every answer is scored, with what to fix and a stronger answer.

Try it free

Frontend architecture

Component structure and architecture

Angular is chosen for large, long-lived applications, so experienced candidates are asked how they split components and organise a codebase that several teams share.

How do you decide when to split a component into smaller ones?Fresher

I split when a component does more than one job, when part of it is repeated elsewhere, or when the template and class grow too large to follow easily. A common split is between container (smart) components and presentational (dumb) ones. A container, like an OrderPage, talks to services, loads data and handles actions. Presentational components, like OrderTable or StatusBadge, only take inputs and emit outputs, so they're easy to reuse, test and run with OnPush.

Don't over-split either: a piece used once, with ten lines of template, doesn't need its own component. Name components by what they show, not by the page they happen to appear on.

How would you organise the folders of a large Angular app with several teams working on it?1-6 years

Organise by feature, not by file type. Instead of one folder for all components, one for services and one for models, each feature such as orders, payments or reports gets its own folder with its components, services, routes and models, and is lazy-loaded. A core area holds app-wide singletons such as authentication, interceptors and the layout shell, and a shared area holds generic UI components, pipes and directives with no business logic.

Set rules on what may import what: features shouldn't reach into each other's internals. In very large apps, an Nx monorepo or Angular libraries make these boundaries enforceable with lint rules and let each team build and test its part alone. Avoid one giant SharedModule that everything imports.

Your company wants a library of reusable components, such as buttons, inputs and date pickers, shared across several Angular apps. How would you build it?1-6 years

Create it as an Angular library (ng generate library), in a monorepo or published as a versioned npm package. Design each component's API carefully: clear inputs and outputs, sensible defaults, and content projection with ng-content so callers can pass their own content instead of a growing list of inputs. Form controls like the date picker should implement ControlValueAccessor, so they work with formControlName and ngModel just like native inputs.

Theme with CSS custom properties or design tokens rather than hard-coded colours, build accessibility in once (keyboard, focus, ARIA), and document every component with live examples, for instance in Storybook. Use semantic versioning and a changelog, since a breaking change affects every app.

Frontend architecture

State management

Enterprise Angular apps share a lot of data between screens, so interviewers ask where state should live and when a store such as NgRx is worth its cost.

Where do you keep state in an Angular app? How do you choose between a component, a service and a store?Fresher

Keep state as close as possible to where it's used. State used by one component, like whether a panel is open or the text in a search box, stays in that component, often in a signal. State several components share, like the logged-in user or the cart, goes in a service provided in root, held in a signal or BehaviorSubject, exposed read-only, and changed only through the service's methods.

A store like NgRx is worth it when many features read and change the same state in complex ways and you want strict, traceable updates. Most apps need much less global state than they think: data from the server is often better treated as a cache than as app state.

When would you introduce NgRx into a project, and what are its main parts?1-6 years

NgRx follows the Redux pattern. Components dispatch actions that describe what happened, like "Order Placed". Reducers are pure functions that take the current state and an action and return new state. Selectors read and derive data from the store, memoised so they recompute only when their inputs change. Effects handle side effects, such as calling the API when an action arrives and dispatching a success or failure action.

It's worth it in large apps with a lot of shared, changing state and many developers, because every change follows one predictable path and the Redux DevTools show each action. The cost is boilerplate and a learning curve. For smaller apps, services with signals, or the lighter NgRx SignalStore, are often enough.

Three components on the same page each call the same /api/categories endpoint. How do you avoid duplicate calls and keep the data fresh?1-6 years

Move the call into a service and share one result. With RxJS: categories$ = this.http.get<Category[]>('/api/categories').pipe(shareReplay(1)), so the first subscriber triggers the request and the others, now and later, receive the same response. Or load it once into a signal in the service and let components read the signal.

Then decide when the cache goes stale: after the user adds a category, update the cached list or fetch it again; for data that changes on the server, refetch after a time limit or when the user comes back to the page. Libraries such as TanStack Query for Angular handle caching and refetching for you. Caching without a plan for refreshing just shows users old data.

Web platform

Browser and networking

Angular apps are large single-page apps, so interviewers check that you understand how the browser loads them, where tokens should live and why the first screen is slow.

What is the difference between async and defer on a script tag? How do scripts affect page loading?Fresher

The browser builds a page by parsing HTML into the DOM and CSS into the CSSOM, then combining them to lay out and paint. A plain script tag stops HTML parsing while the script downloads and runs, which delays the page. async downloads the script in parallel and runs it as soon as it arrives, in no fixed order, pausing parsing briefly; it suits independent scripts like analytics. defer also downloads in parallel but runs the scripts in order after the HTML is parsed, just before DOMContentLoaded; it suits scripts that need the DOM.

Angular's build output uses module scripts, which are deferred by default. CSS also blocks rendering, so keep the CSS needed for the first screen small.

Where should an Angular app keep the user's login token: localStorage or a cookie?1-6 years

localStorage is simple: an interceptor reads the token and adds it to the Authorization header. But any JavaScript on the page can read it, so one XSS bug, or a compromised third-party script, can steal it. An HttpOnly, Secure cookie can't be read by JavaScript at all; the browser sends it automatically, so requests need withCredentials and the API needs matching CORS settings. The trade-off is CSRF, which SameSite cookies and a CSRF token handle.

For most apps with their own backend, the HttpOnly cookie is safer. If tokens must live in JavaScript, keep the access token short-lived and in memory. Either way, preventing XSS is the real protection: Angular sanitises template values, so avoid bypassSecurityTrust methods unless truly needed.

Your Angular app takes eight seconds to show its first screen on a mid-range phone. How do you find out why and speed it up?1-6 years

Measure first: run Lighthouse in mobile mode and look at Largest Contentful Paint and main-thread time, check the Network panel with throttling, and look at the bundle sizes from ng build, with a tool like source-map-explorer to see what's inside. Common causes are a huge initial bundle, large libraries imported whole, unoptimised images, and API calls that block anything from rendering.

Fixes: lazy-load routes so the first screen downloads only its own code, use @defer blocks for heavy parts below the fold, trim or replace heavy libraries, use NgOptimizedImage for properly sized, lazy-loaded images, enable compression and long caching for hashed files, and consider server-side rendering with hydration. Measure again after each change.

Testing

Component testing

Angular's CLI sets up testing for every project, and enterprise teams expect developers to test components, services and async behaviour with TestBed.

What is TestBed in Angular testing, and why do you call fixture.detectChanges()?Fresher

TestBed creates a small Angular environment for a test. You configure it with the component under test (in imports, for a standalone component) and the providers it needs, often fakes; then createComponent gives you a ComponentFixture, which holds the component instance and its rendered DOM through fixture.nativeElement or debugElement.

In tests, change detection doesn't run on its own, so after setting an input or changing data you call fixture.detectChanges() to update the template; the first call also runs ngOnInit. Forgetting it is the most common reason a test sees an empty or out-of-date DOM. Angular projects have traditionally used Jasmine with Karma, and newer setups use Jest or Vitest, but TestBed works the same way.

How do you test a component whose service calls HttpClient? Would you mock the service or the HTTP layer?1-6 years

For a component test, mock the service: provide a fake in TestBed with { provide: OrderService, useValue: fakeService }, whose methods return of(orders) or throwError(() => error) from RxJS. Then check the component shows the orders, or the error message. The test stays fast and doesn't depend on URLs.

For the service itself, test the HTTP layer with provideHttpClient() and provideHttpClientTesting() (HttpClientTestingModule in older code). Call the service method, use HttpTestingController's expectOne to check the URL and method, flush a fake response or an error, and finish with verify() to make sure no unexpected requests were made. Testing at both levels catches different bugs.

How would you test a search box that waits 300 ms (debounceTime) before calling the API?1-6 years

Wrap the test in fakeAsync, which runs it on a fake clock. Set the input's value and dispatch an input event, call fixture.detectChanges(), then tick(299) and check the service's search method hasn't been called; then tick(1) and check it was called once with the term. Typing twice within 300 ms and checking for a single call proves the debounce works.

The service is a spy returning of(results), so after the tick you can also check the results render. This tests the behaviour the user cares about without waiting in real time. If a test finishes with timers still pending, fakeAsync fails with an error, which helps catch leaks. Jest and Vitest have fake timers that do the same.

Every job

HR and behavioural round

Many Angular roles are on long enterprise and client projects, so the HR round checks how you work with clients, reviewers and changing requirements, not only your technical skill.

Tell me about yourself.Fresher

Keep it to a minute, focused on Angular and what you've built. For example: "I'm a [degree] graduate from [college], and for the last [time] I've been building web apps in Angular with TypeScript and RxJS. My main project is [project], a [what it does], where I built [feature: a 20-field application form with reactive forms, role-based routing] and [result]. I've also worked with REST APIs from a [Spring Boot / .NET / Node] backend. I'm looking for an Angular role on a large application where I can learn good architecture."

If you're experienced, swap the college for your current role and the biggest module you own.

Why Angular? Would you work in React if a project needed it?Fresher

Give real reasons and show you're flexible. For example: "I like that Angular gives a complete structure: routing, forms, HTTP and testing are built in, and TypeScript and dependency injection keep large apps consistent, which is why many enterprise projects use it. But the fundamentals are the same in any framework: components, state, HTTP and the browser. If a project needed React, I'd learn it quickly; I've already [built a small React app / read its documentation] and found the ideas familiar."

Don't criticise other frameworks: the interviewer's next project might use one of them.

You may be placed on a maintenance project for a client's old application. Are you okay with that?Fresher

Be honest and positive, and show you see the value in it. For example: "Yes. Working on an existing application teaches things a new project doesn't: reading other people's code, fixing real users' problems, and changing code safely without breaking it. I'd want to understand the application well first, and over time I'd like to improve it, for example by [upgrading it to a newer Angular version / adding tests to the fragile parts]. In the longer run I'd like to work on new development too."

If you have a real constraint, say so politely, but don't make the answer sound like a condition for joining.

Tell me about a time you disagreed with a reviewer's comment on your code.1-6 years

Show that you discuss with reasons, stay open, and care about the result more than winning. Use STAR: "A senior reviewer asked me to move a screen's state into NgRx (situation). I felt it would add a lot of code for a simple screen (task). I explained my reasoning in the review, showed a version using a service with signals, and asked what problem they wanted to avoid. Their worry was a second screen needing the same data, which was fair (action). We kept the service, made it shared, and agreed to revisit NgRx if more screens needed it (result)."

Also show that you accept the decision once it's made.

The client asks for a big change two days before the sprint ends. How do you handle it?1-6 years

Show that you neither refuse outright nor quietly overwork and ship poor quality. A structure: understand the change, estimate it, make the trade-off visible, let the right person decide. For example: "I'd ask what problem the change solves and how urgent it is, give a quick estimate, and tell the lead or scrum master what it would push out. If it's urgent, we swap it for work of a similar size; if not, it goes into the next sprint. Once a client wanted a new filter on a report; we delivered a simple version on time and the full one the next sprint."

Never promise a date you haven't estimated.

Free interview questions, roadmaps and mock interviews: https://myskillgrid.com/interview-questions/angular-developer/

Ready to answer them for real?

Your first Angular Developer mock interview is free: 3 questions, a score and feedback for each, and a stronger answer to learn from, in about 10 minutes.