Skip to content

Angular Interview

Angular

  • 1. What is Angular?

    Angular is a Typescript based free and open-source web application framework led by the Angular Team at Google and by a community of individuals and corporations. -Wikipedia

    Angular is a component based framework for building scalable applications consisting of a collection of well integrated libraries that cover a wide variety of features including routing, form management, client-server communication and more. -Angular.io

    Angular is a front-end framework for building dynamic single-page applications. It uses TypeScript, is component-based, and supports powerful features like dependency injection, routing, and reactive programming.

  • 2. What are Structural Directives? Can You Give Examples?

    Structural Directives - directives which change the DOM layout by adding and removing DOM elements. (*ngFor, *ngIf, *ngSwitch)

  • 3. How Does Angular Bootstrap Your Application?

    main.ts : is entry point of our application. This file bootstrap app.module.ts file.

    app.module.ts: This file boostrap our first component. i.e app.component.ts

    app.component.ts: This fille render app.component.html file.

    app.component.html: Final HTML template

    Screenshot 2024-12-27 at 15.26.55

    Angular bootstraps the root module (usually AppModule) to start the application by loading the main component and initializing the application.

    main.ts : bootstrapModule(AppModule) -> App/app.moudule.ts: boostrap: AppComponent -> AppComponent.ts is root component is rendered attached attached to the index.html file's <app-root> element.

  • 4. What is the Shadow DOM?

    The Shadow DOM can be thought of as a parallel DOM tree, separate from the actual DOM. The Shadow DOM allows groups of DOM implementation to be hidden inside a single element and encapsulates styles to the element.

    Shadow DOM Terminology:

    • Shadow Host - the regular DOM node that the shadow DOM is attached to
    • Shadow Tree - The DOM tree inside the Shadow DOM
    • Shadow Boundary - the place where the Shadow DOM ends, and the regular DOM begins
    • Shadow Root - the root node of the Shadow Tree
  • 5. What is an HTTP Interceptor? What Are Some Keywords?

    HTTP Interceptors intercept HTTP requests and responses, allowing modifications (e.g., adding headers, handling errors). Keywords include HttpInterceptor, intercept, and HttpHandler.

    @Injectable ()
    export class AuthInterceptor implements HttpInterceptor {
      constructor(){}
      // 拦截方法
      intercept (
         // unknown 指定请求体(body)的类型
         request: HttpRequest<unknown>, 
     next: HttpHandler
         // unknown 指定响应内容(body)的类型
     ): Observable<HttpEvent<unknown>>{
         // 克隆并修改请求头
         const req = request.clone({
             setHeaders: {
                 Authorization: "Bearer xxxxxxx"
             }
     })
         // 通过回调函数将修改店的请求头回传给应用
         return next.handle(req)
     }
    }
    
  • 6. What is the Difference Between Reactive and Template-Driven Forms?

    • Reactive Forms: Code-driven, more control over form behavior and validation.
    • Template-Driven Forms: Template-driven, simpler, suitable for small forms.

    In Angular, forms are essential for capturing user input, validating data, and submitting it for processing. Angular provides two approaches for creating forms: Template-Driven Forms and Reactive Forms.

    Template-Driven Forms are defined in the HTML template using Angular directives like ngModel, making them simpler and ideal for small forms.

    On the other hand, Reactive Forms are built programmatically in TypeScript using FormControl, FormGroup, and Validators, providing better control and scalability, especially for complex and dynamic forms. Both approaches enable efficient form handling, but Reactive Forms are recommended for large-scale applications due to their testability and centralized validation logic.

  • 7. How Are Directives Different from Components?

    Directives add behavior to elements, while components have a template and define a section of the UI.

    Directives are more general-purpose tools that extend or modify the behavior of existing DOM elements or components, and they don’t include a template of their own.

    Components are a specialized type of directive designed for building and controlling views, and they always come with their own HTML template.

  • 8. What Makes Up an Angular View?

    Components define views, which are sets of screen elements that Angular can choose among and modify according to your program logic and data.

    Components use services, which provide specific functionality not directly related to views. Services can be injected as dependencies, making your code more modular, reusable, and efficient.

    Modules, components and services are classes that use decorators.

    The decorators mark their type and provide metadata that tells Angular how to use them.

    An Angular view is defined by a component's template and associated styles. The view is what the user interacts with on the screen.

  • 9. How Can We Handle Routing in Our Angular Applications?

    Angular Router manages navigation, using RouterModule, RouterLink, and configuring routes with app-routing.module.ts.

  • 10. What is FormBuilder?

FormBuilder is a service in Reactive Forms that simplifies creating and managing form controls.

FormBuilder - short-hand for FormGroup and FormControl

  • 11. Explain Each Keyword Used in NgModule.

NgModules configure the injector and the compiler and help organize related things together.

An NgModule is a class marked by the @NgModule decorator. @NgModule takes a metadata object that describes how to compile a component’s template and to create an injector at runtime. It defines the module’s own components, directives, and pipes, making some of them public through the exports property, so that external components can use them.

Angular libraries are NgModules

  • FormsModule (@angular/forms)
  • HttpClientModule (@angular/common/http)
  • RouterModule (@angular/router)

@NgModule has five fields:

  • Declarations - lists the components, directives and pipes that are part of this module
  • Imports - lists the other modules used by this module
  • Exports - lists the declarations can be used by other module
  • Providers - list of services other components can use (Dependency Injection)
  • Bootstrap - identifies the root component of the module. When Angular loads the AppModule, it looks for the bootstrap metadata and loads all the components listed.
  • 12. What is a Service and Dependency Injection?

Services contain reusable logic.

Dependency Injection (DI) in Angular provides services to components or other services as dependencies.

  • 13. How is an Observable Different from a Promise?

Observables can handle multiple values over time, are lazy, and allow operators for transformation.

Promises haHow can we conditionally render an elementndle one asynchronous result and are eager.

  • 14. What is a Pipe?

Pipes transform data in templates, such as formatting dates or converting text to uppercase.

  • Pipes are used to transform data
  • Denoted with the | character
  • Custom Pipes
  • Common pipes: 1. object | json 2. string | uppercase 3. string | lowercase 4. number | percent 5. number | decimal
  • 15. How Can We Protect Our Routes When Users Are Not Logged In?

Use route guards like CanActivate to check authentication before allowing navigation.

  • 16. What is a BehaviorSubject?

A BehaviorSubject is an Observable that holds a current value and emits it to new subscribers immediately.

  • 17. How Can We Pass Data Between Components?

Use @Input and @Output for parent-child communication, or a shared service with Observables for sibling components.

  • Parent to child:
  • Using @Input() to pass data down to child components.

  • Child to parent:

  • Using @Output() and EventEmitter to send data back to the parent.
  • Sharing Data via @ViewChild()

  • Unrelated Components

  • Using shared services or state management libraries (NgRx)
  • 18. How Do We Catch Errors in Observables?

Use the catchError operator in the Observable pipeline to handle errors.

  • 19. What is the Default Testing Library in Angular? The Test Runner?

Angular uses Jasmine for testing and Karma as the test runner.

  • 20. What is Property Binding?

Property Binding binds DOM properties to component properties, updating the view based on component state changes.

Property binding in Angular helps you set values for properties of HTML elements or directive. User property binding to do things such as toggle button functionality, set paths programmatically, and share values between components. Property binding moves a value in one direction, from a component’s property into a target HTML element property.

To bind to an element’s property, enclose it in square brackets.

  • 21. How Can We Create Custom Directives?

Use the @Directive decorator to create a custom directive and add behavior to DOM elements.

  • We can define our own custom Structural or Attribute Directives
  • @Input set - setter property which will intercept and act upon a value from the parent
  • ViewContainerRef - represents a container where one or more views can be attached
  • TemplateRef - represents an embedded template that can be used to instantiate embedded views
  • ElementRef - A wrapper around a native element inside the view
  • 22. What is the File Compilation Order When an Angular Application Starts?

Angular compiles modules, then components, then renders the root component, initializing services and resolving routes.

  • 23. What is the Purpose of the polyfills.ts File?

polyfills.ts enables compatibility with older browsers by filling gaps in modern JavaScript features.

polyfills.ts plays a critical role in making Angular applications browser-compatible. It ensures modern JavaScript features and Angular-specific functionalities work consistently, regardless of the browser version.

  • 24. What is a Subject?

A Subject is an Observable that can also be an observer, allowing it to multicast values to multiple subscribers.

  • 25. How Can We Emit Values Through Observables?

Use Subject, BehaviorSubject, or ReplaySubject to emit values. Use next() to push values to subscribers.

  • 26. What is ngModel?

ngModel binds form controls to component properties, enabling two-way data binding in Template-Driven Forms.

[(ngModel)] - a directive used to reconcile value changes in the attached element with changes in the data model. This allows us to respond to user input with validation and error handling

  • 27. How Can We Make HTTP Requests?

Use Angular's HttpClient to make HTTP requests like GET, POST, PUT, and DELETE.

  • 28. How Can We Conditionally Render an Element?

Use Structural Directives like *ngIf or *ngSwitch to conditionally render elements.

  • 29. What is NgRx?

NgRx is a state management library for Angular, based on Redux, allowing predictable state management using actions, reducers, and selectors.

  • 30. How is a Subject Different from an Observable?

A Subject is both an Observable and an Observer, enabling multicast. An Observable only emits data, while a Subject can also receive and emit data.

  • 31. When Does ngOnChanges Run?

ngOnChanges runs when an @Input property of a component changes, updating the component based on new inputs.

ngOnChanges - respond when Angular sets or resets data-bound input properties. (@angular/core)

  • 32. What is Change Detection? What Are the Different Strategies?

Change detection updates the view when data changes.

Change detection is the process by which Angular determines what parts of the DOM need to be updated when the application state changes. It is triggered during events like user input, HTTP requests, or timers.

Strategies:

  • Default: Detects changes for every event.
  • OnPush: Detects changes only when input properties change.
  • 33. What are Some Benefits of TypeScript?

TypeScript offers static type checking, better readability, enhanced IDE support, and easier refactoring for large codebases.

  • 34. What is the Difference Between ng-template, ng-container, and ng-content?
  • ng-template: Defines template content without rendering it.
  • ng-container: Groups elements without adding extra HTML.
  • ng-content: Projects content into components.
  • 35. What is the Difference Between RxJS of and from?
  • of: Converts values to an Observable as-is.
  • from: Converts an array or promise into an Observable.
  • 36. What Does the Async Pipe Do?

The async pipe subscribes to Observables or Promises, automatically handling subscriptions and updates in templates.

  • 37. What is a ReplaySubject?

A ReplaySubject re-emits previous values to new subscribers, useful for providing recent data to late subscribers.

  • 38. What are Some RxJS Operators?

Common operators include:

  • map: Transforms each value.
  • filter: Filters values based on a condition.
  • mergeMap: Flattens multiple Observables into one.
  • catchError: Handles errors in the Observable pipeline.
  • switchMap: Cancels previous Observables and switches to the latest one.
  • 39. How to share state between A and B components in Angular?
  1. Using a Shared Service (Best for Unrelated Components)

A shared service is the most common and scalable way to share state between unrelated or sibling components in Angular.

Steps:

  1. Create a Service:

     import { Injectable } from '@angular/core';
    import { BehaviorSubject } from 'rxjs';
    
    @Injectable({
         providedIn: 'root',
    })
    export class SharedStateService {
      private state = new BehaviorSubject<string>(''); // Initial state
      currentState$ = this.state.asObservable(); // Observable for subscribers
    
      updateState(newState: string) {
           this.state.next(newState); // Update the state
      }
    }
    
  2. Update State in Component A:

     import { Component } from '@angular/core';
    import { SharedStateService } from './shared-state.service';
    
    @Component({
         selector: 'app-component-a',
      template: `
        <input [(ngModel)]="data" placeholder="Enter data">
        <button (click)="shareState()">Share State</button>
      `,
    })
    export class ComponentA {
      data = '';
    
      constructor(private sharedStateService: SharedStateService) {}
    
      shareState() {
           this.sharedStateService.updateState(this.data);
      }
    }
    
  3. Receive State in Component B:

     import { Component, OnInit } from '@angular/core';
    import { SharedStateService } from './shared-state.service';
    
    @Component({
         selector: 'app-component-b',
      template: `<p>Shared State: {{ sharedData }}</p>`,
    })
    export class ComponentB implements OnInit {
      sharedData = '';
    
      constructor(private sharedStateService: SharedStateService) {}
    
      ngOnInit() {
           this.sharedStateService.currentState$.subscribe((state) => {
          this.sharedData = state;
        });
      }
    }
    
  • Use Case: Sharing state between unrelated components or components that don't have a direct relationship in the component tree.

2. Using Input and Output (Parent-Child Communication)

If Component A is a parent of Component B, you can share state through @Input (parent to child) and @Output (child to parent).

Steps:

  1. Pass Data to Child Component via @Input:

    • Parent (Component A):
     import { Component } from '@angular/core';
    
    @Component({
           selector: 'app-component-a',
      template: `<app-component-b [parentData]="data"></app-component-b>
                 <input [(ngModel)]="data" placeholder="Update Parent Data">`,
    })
    export class ComponentA {
      data = 'Initial Data';
    }
    
    • Child (Component B):
     import { Component, Input } from '@angular/core';
    
    @Component({
           selector: 'app-component-b',
      template: `<p>Data from Parent: {{ parentData }}</p>`,
    })
    export class ComponentB {
      @Input() parentData!: string;
    }
    
  2. Emit Data to Parent Component via @Output:

    • Child (Component B):
     import { Component, Output, EventEmitter } from '@angular/core';
    
    @Component({
           selector: 'app-component-b',
      template: `
        <button (click)="sendData()">Send Data to Parent</button>
      `,
    })
    export class ComponentB {
      @Output() dataEmitter = new EventEmitter<string>();
    
      sendData() {
             this.dataEmitter.emit('Data from Child');
      }
    }
    
    • Parent (Component A):
     <app-component-b (dataEmitter)="handleData($event)"></app-component-b>
    

3. Using Angular Router and state

If you navigate between Component A and Component B, you can pass state using Angular's router.

Steps:

  1. Navigate with State:

     import { Router } from '@angular/router';
    
    constructor(private router: Router) {}
    
    navigateWithState() {
         this.router.navigate(['/component-b'], {
        state: { sharedData: 'Data from Component A' },
      });
    }
    
  2. Retrieve State in Component B:

     import { Component } from '@angular/core';
    import { Router } from '@angular/router';
    
    @Component({
         selector: 'app-component-b',
      template: `<p>State from A: {{ sharedData }}</p>`,
    })
    export class ComponentB {
      sharedData = '';
    
      constructor(private router: Router) {
           const navigation = this.router.getCurrentNavigation();
        this.sharedData = navigation?.extras.state?.['sharedData'] || '';
      }
    }
    
  • Use Case: Passing state when navigating between pages/components.
  1. Using a State Management Library (NgRx or Akita)

For complex applications, use a state management library to handle shared state efficiently across multiple components.

Example with NgRx:

  1. Define State and Actions:
  • Create a store to hold shared data.
  1. Update State:
    • Dispatch actions to modify state from Component A.
  2. Access State:
    • Select state from the store in Component B.
  • Use Case: Large-scale applications requiring centralized and predictable state management
  • 40. How to do error handling in Angular?

HTTP Interceptors: Centralize API error handling globally.

Custom Error Pages: Configure routes for errors like 404 or 500.

Global Error Handler: Implement a custom ErrorHandler to capture uncaught exceptions.

Try-Catch: Wrap service calls in components with error handling

  • 41. Benefits of Angular vs plain HTML and CSS

Dynamic Content: Angular supports dynamic content rendering with data binding, while HTML is static.

Component-based Architecture: Promotes reusable, maintainable, and testable code.

Dependency Injection (DI): Facilitates better separation of concerns and modular development.

Two-way Data Binding: Automatically syncs data between the model and the view.

Routing and SPA Support: Provides in-built tools for routing, making it ideal for single-page applications (SPAs).

Built-in Directives: Extends HTML with custom behavior, while plain HTML lacks dynamic interaction.

  • 42. Angular lifecycle of components

ngOnInit: Executes after the component is initialized, used for initial data fetching or setup.

ngAfterContentInit: Runs after projecting content into the component's view.

ngAfterViewInit: Runs after initializing the component's view and child views.

ngOnChanges: Triggered when input properties of a component are updated.

ngDoCheck: Called during change detection for manual checks on data binding.

ngAfterContentChecked: Triggered after every content projection check.

ngAfterViewChecked: Called after every check of the component’s view and child views.

ngOnDestroy: Executes just before the component is destroyed, used for cleanup tasks.

  • 43. Lazy loading in Angular

Lazy loading is a technique to load modules or components only when they are needed, reducing the initial load time of the application. It works by:

  1. Defining routes for different modules.
  2. Using the loadChildren property in the RouterModule configuration.
  3. The required module is loaded dynamically when the user navigates to its route.
const routes: Routes = [
  { path: 'dashboard', loadChildren: () => import('./dashboard/dashboard.module').then(m => m.DashboardModule) }
];
  • 44. How to protect routes when users are not logged in?

Use Angular route guards (CanActivate):

  1. Implement CanActivate in a guard service.
  2. Check authentication or authorization logic.
  3. Redirect unauthorized users to a login page.
@Injectable({ providedIn: 'root' })
export class AuthGuard implements CanActivate {
  constructor(private authService: AuthService, private router: Router) {}
  canActivate(): boolean {
    if (this.authService.isLoggedIn()) {
      return true;
    }
    this.router.navigate(['/login']);
    return false;
  }
}
  • 45. Difference between Promise and Observable
Feature Promise Observable
Execution Executes immediately. Executes lazily (on subscription).
Data Emission Emits a single value. Emits multiple values over time.
Operators Lacks built-in operators for data handling. Provides rich operators (e.g., map, filter).
Cancellation Cannot be cancelled. Can be cancelled using unsubscribe().
  • 46. Difference between BehaviorSubject and Subject
Feature Subject BehaviorSubject
Initial Value Does not have an initial value. Requires an initial value.
Latest Value Does not store the latest value. Stores the latest emitted value.
Subscribers Only new emissions are received. New subscribers receive the latest value.

Angular

Basics

● Component

● Template

● Directive

● Binding

● Pipe

● Service

● HttpClient

● Routing

● Event

● Module

● Testing

● Build

● Deployment

jest' library: report

React testing library: component r

jesmine + karma built in

spec.ts -> test