All jobs / Frontend / web developer

Angular interview questions

Angular questions a Frontend / web developer can be asked, from first job to senior. Open one to see the strongest answer and why it works.

  1. In Angular, how does a parent component pass data to a child, and how does the child tell the parent something happened?

    The strongest answer: Data goes down through an input on the child, bound with square brackets; events come up through an output the child emits, bound with parentheses — the child never reaches into the parent

    Why it works: Exactly — properties down, events up. With decorators or the newer input() and output() functions, the contract is the same.

    • Properties down, events up.
    • Input: [value] binding on the child.
    • Output: (changed) event to the parent.
    • Shared service only for distant components.
  2. In an Angular component, what belongs in the constructor and what belongs in ngOnInit?

    The strongest answer: The constructor is for dependency injection and trivial setup; input values are not bound yet. ngOnInit runs once after the first inputs are set, so initial loading that needs them goes there

    Why it works: Right — Angular creates the class first and binds inputs after. ngOnInit is the first point where the component knows its inputs.

    • Construct, then bind, then init.
    • Constructor: inject dependencies only.
    • ngOnInit: work that needs inputs.
    • Never wait for inputs with timers.
  3. A component subscribes to a long-lived observable from a service in ngOnInit. After navigating back and forth, the handler fires several times per event.

    What is happening, and how do you fix it?

    The strongest answer: Each visit adds a subscription that outlives the destroyed component. Let the async pipe subscribe in the template, or end it with takeUntilDestroyed or an unsubscribe in ngOnDestroy

    Why it works: Exactly — a long-lived source keeps every subscriber alive. The async pipe or takeUntilDestroyed ties the subscription to the component’s life.

    • Every manual subscribe needs an end.
    • Prefer the async pipe.
    • Or takeUntilDestroyed / ngOnDestroy.
    • Don’t use take(1) on live streams.
  4. An Angular app has an admin area most users never open and must not enter. How do you set up its routes?

    The strongest answer: Lazy-load the admin routes with loadChildren or loadComponent, put a guard on them that redirects users without the role, and keep enforcing permissions in the API — a guard is only navigation

    Why it works: Right — lazy loading keeps admin code out of the main bundle, the guard handles the experience, and the server is the real lock.

    • Lazy route, guard, server check.
    • loadChildren or loadComponent for admin.
    • Guard redirects; it does not secure.
    • The API enforces the role.
  5. A checkout form has conditional sections, a confirm-email field that must match, and rules that change with the delivery country.

    Template-driven or reactive forms, and where do the rules live?

    The strongest answer: Reactive forms: the model and validators live in the class, the match rule is a group-level validator, country changes swap validators in code, and all of it is unit-testable without the DOM

    Why it works: Exactly — complex, dynamic rules belong in an explicit form model. A validator on the group sees both fields, and typed controls catch mistakes early.

    • Dynamic rules need a form model.
    • Reactive forms for complex validation.
    • Cross-field rules: validator on the group.
    • Test validators without rendering.
  6. The header and the cart page both inject CartService. Items added on the cart page never appear in the header badge.

    What do you suspect, and how do you confirm and fix it?

    The strongest answer: Two instances: the service is provided again somewhere — a component’s providers array or a lazy-loaded area — so that subtree gets its own copy. Provide it once, in root, and delete the extra provider

    Why it works: Right — Angular’s injector is hierarchical; a provider lower in the tree shadows the root one. One provider, one cart.

    • Injectors are hierarchical.
    • Look for a second provider.
    • Provide shared state once, in root.
    • Component providers mean per-component instances.
  7. In RxJS, which flattening operator do you use for a typeahead search, and which for a Save button, and why?

    The strongest answer: switchMap for search: a new term cancels the previous request, so stale results never land. exhaustMap for Save: extra clicks are ignored while one is in flight — or concatMap if each must run in order

    Why it works: Exactly — the operator is a concurrency policy: cancel, ignore, queue or run in parallel. Pick per interaction.

    • The operator is the concurrency policy.
    • switchMap: cancel the previous.
    • exhaustMap: ignore while busy.
    • concatMap: queue; mergeMap: parallel.
  8. A large Angular app is built from dozens of NgModules, including a shared module that imports almost everything. The team wants standalone components.

    How do you plan the move?

    The strongest answer: Incrementally: new code is standalone now; migrate leaves first, one feature at a time, using the official schematic; replace the catch-all shared module with explicit imports; ship after every step

    Why it works: Right — standalone and NgModules interoperate, so nothing forces a big bang. Explicit imports also expose what each component really depends on.

    • Migrate at the edges, keep shipping.
    • New code standalone today.
    • Leaves first, feature by feature.
    • Replace the shared module with explicit imports.
  9. A team proposes adopting NgRx for the whole app because “state is getting messy”. Most screens are forms over a REST API; two areas have state shared across many components.

    What do you decide?

    The strongest answer: Diagnose first. Server data stays in services exposing signals or observables; the two shared areas get a focused store; a full store everywhere only if many writers, undo or audit needs justify the ceremony

    Why it works: Exactly — “messy” is a symptom. Separate server cache from shared client state, then buy the amount of structure each one needs.

    • Fit the structure to the state.
    • Separate server data from client state.
    • Store only where sharing is real.
    • One approach per kind of state.