or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

directives.mdhttp.mdi18n.mdindex.mdlocation.mdpipes.mdplatform.mdtesting.md
tile.json

http.mddocs/

HTTP Client

Angular's HTTP client provides a powerful, feature-rich solution for making HTTP requests with full TypeScript support, interceptors, error handling, request/response transformation, and comprehensive testing utilities.

Capabilities

HTTP Client Core

HttpClient - Main HTTP Service

The primary service for making HTTP requests with full Observable support and type safety.

/**
 * Performs HTTP requests and returns observables of the response
 * Supports all HTTP methods with full type safety and configuration options
 */
export class HttpClient {
  /** Make a generic HTTP request with full control over the request */
  request<R>(req: HttpRequest<any>): Observable<HttpEvent<R>>;
  request<R>(method: string, url: string, options?: HttpRequestOptions & { observe?: 'body'; responseType?: 'json' }): Observable<R>;
  request<R>(method: string, url: string, options: HttpRequestOptions & { observe: 'events'; responseType?: 'json' }): Observable<HttpEvent<R>>;
  request<R>(method: string, url: string, options: HttpRequestOptions & { observe: 'response'; responseType?: 'json' }): Observable<HttpResponse<R>>;
  request(method: string, url: string, options: HttpRequestOptions & { observe: 'events'; responseType: 'text' }): Observable<HttpEvent<string>>;
  request(method: string, url: string, options: HttpRequestOptions & { observe: 'response'; responseType: 'text' }): Observable<HttpResponse<string>>;
  request(method: string, url: string, options?: HttpRequestOptions & { responseType: 'text' }): Observable<string>;

  /** Perform GET request */
  get<T>(url: string, options?: HttpRequestOptions & { observe?: 'body'; responseType?: 'json' }): Observable<T>;
  get(url: string, options: HttpRequestOptions & { observe: 'events'; responseType?: 'json' }): Observable<HttpEvent<Object>>;
  get(url: string, options: HttpRequestOptions & { observe: 'response'; responseType?: 'json' }): Observable<HttpResponse<Object>>;
  get(url: string, options: HttpRequestOptions & { observe: 'events'; responseType: 'text' }): Observable<HttpEvent<string>>;
  get(url: string, options: HttpRequestOptions & { observe: 'response'; responseType: 'text' }): Observable<HttpResponse<string>>;
  get(url: string, options?: HttpRequestOptions & { responseType: 'text' }): Observable<string>;
  get(url: string, options: HttpRequestOptions & { responseType: 'blob' }): Observable<Blob>;
  get(url: string, options: HttpRequestOptions & { responseType: 'arraybuffer' }): Observable<ArrayBuffer>;

  /** Perform POST request */
  post<T>(url: string, body: any | null, options?: HttpRequestOptions & { observe?: 'body'; responseType?: 'json' }): Observable<T>;
  post(url: string, body: any | null, options: HttpRequestOptions & { observe: 'events'; responseType?: 'json' }): Observable<HttpEvent<Object>>;
  post(url: string, body: any | null, options: HttpRequestOptions & { observe: 'response'; responseType?: 'json' }): Observable<HttpResponse<Object>>;

  /** Perform PUT request */
  put<T>(url: string, body: any | null, options?: HttpRequestOptions & { observe?: 'body'; responseType?: 'json' }): Observable<T>;

  /** Perform PATCH request */
  patch<T>(url: string, body: any | null, options?: HttpRequestOptions & { observe?: 'body'; responseType?: 'json' }): Observable<T>;

  /** Perform DELETE request */
  delete<T>(url: string, options?: HttpRequestOptions & { observe?: 'body'; responseType?: 'json' }): Observable<T>;

  /** Perform HEAD request */
  head<T>(url: string, options?: HttpRequestOptions & { observe?: 'body'; responseType?: 'json' }): Observable<T>;

  /** Perform OPTIONS request */
  options<T>(url: string, options?: HttpRequestOptions & { observe?: 'body'; responseType?: 'json' }): Observable<T>;

  /** Perform JSONP request */
  jsonp<T>(url: string, callbackParam: string): Observable<T>;
}

/** Options for HTTP requests */
interface HttpRequestOptions {
  headers?: HttpHeaders | { [header: string]: string | string[] };
  context?: HttpContext;
  observe?: 'body' | 'events' | 'response';
  params?: HttpParams | { [param: string]: string | number | boolean | ReadonlyArray<string | number | boolean> };
  reportProgress?: boolean;
  responseType?: 'arraybuffer' | 'blob' | 'json' | 'text';
  withCredentials?: boolean;
}

Usage Examples:

@Injectable()
export class ApiService {
  constructor(private http: HttpClient) {}

  // Basic GET request
  getUsers(): Observable<User[]> {
    return this.http.get<User[]>('/api/users');
  }

  // GET with parameters
  getUserById(id: number): Observable<User> {
    return this.http.get<User>(`/api/users/${id}`);
  }

  // GET with query parameters
  getFilteredUsers(filters: UserFilters): Observable<User[]> {
    const params = new HttpParams()
      .set('role', filters.role)
      .set('active', filters.active.toString())
      .set('page', filters.page.toString());

    return this.http.get<User[]>('/api/users', { params });
  }

  // POST request
  createUser(user: CreateUserRequest): Observable<User> {
    return this.http.post<User>('/api/users', user);
  }

  // PUT request
  updateUser(id: number, user: UpdateUserRequest): Observable<User> {
    return this.http.put<User>(`/api/users/${id}`, user);
  }

  // DELETE request
  deleteUser(id: number): Observable<void> {
    return this.http.delete<void>(`/api/users/${id}`);
  }

  // Request with custom headers
  getProtectedData(): Observable<any> {
    const headers = new HttpHeaders({
      'Authorization': 'Bearer ' + this.authService.getToken(),
      'Content-Type': 'application/json'
    });

    return this.http.get('/api/protected', { headers });
  }

  // Full response with status
  getUserWithStatus(id: number): Observable<HttpResponse<User>> {
    return this.http.get<User>(`/api/users/${id}`, { observe: 'response' });
  }

  // Progress tracking for file upload
  uploadFile(file: File): Observable<HttpEvent<any>> {
    const formData = new FormData();
    formData.append('file', file);

    return this.http.post('/api/upload', formData, {
      reportProgress: true,
      observe: 'events'
    });
  }

  // Different response types
  downloadFile(): Observable<Blob> {
    return this.http.get('/api/files/download', { responseType: 'blob' });
  }

  getTextData(): Observable<string> {
    return this.http.get('/api/text', { responseType: 'text' });
  }
}

HTTP Request and Response Types

HttpRequest - Request Representation

Immutable representation of an HTTP request.

/**
 * Immutable object representing an HTTP request
 * Contains all information needed to make the request
 */
export class HttpRequest<T> {
  /** Request body */
  readonly body: T | null;
  /** Request headers */
  readonly headers: HttpHeaders;
  /** Request context for interceptors */
  readonly context: HttpContext;
  /** Whether to report upload/download progress */
  readonly reportProgress: boolean;
  /** Whether to send credentials */
  readonly withCredentials: boolean;
  /** Expected response type */
  readonly responseType: 'arraybuffer' | 'blob' | 'json' | 'text';
  /** HTTP method */
  readonly method: string;
  /** Query parameters */
  readonly params: HttpParams;
  /** Complete URL with parameters */
  readonly urlWithParams: string;

  constructor(method: string, url: string, third?: T | HttpRequestInit, fourth?: HttpRequestInit);

  /** Serialize the request body for transmission */
  serializeBody(): ArrayBuffer | Blob | FormData | URLSearchParams | string | null;

  /** Detect content type header for the request */
  detectContentTypeHeader(): string | null;

  /** Create a clone of this request with optional modifications */
  clone(): HttpRequest<T>;
  clone(update: HttpRequestInit & { body?: any }): HttpRequest<any>;
  clone<V>(update: HttpRequestInit & { body?: V }): HttpRequest<V>;
}

/** Configuration for HttpRequest constructor */
interface HttpRequestInit {
  headers?: HttpHeaders;
  context?: HttpContext;
  reportProgress?: boolean;
  params?: HttpParams;
  responseType?: 'arraybuffer' | 'blob' | 'json' | 'text';
  withCredentials?: boolean;
}

HttpResponse - Response Representation

Represents a successful HTTP response with full metadata.

/**
 * Full HTTP response with body, headers, and status information
 * Extends HttpResponseBase with the response body
 */
export class HttpResponse<T> extends HttpResponseBase {
  /** Response body */
  readonly body: T | null;
  /** Response type indicator */
  readonly type: HttpEventType.Response;

  constructor(init?: HttpResponseInit<T>);

  /** Create a clone of this response with optional modifications */
  clone(): HttpResponse<T>;
  clone(update: HttpResponseInit<T>): HttpResponse<T>;
  clone<V>(update: HttpResponseInit<V>): HttpResponse<V>;
}

/** Base class for HTTP responses */
export abstract class HttpResponseBase {
  /** Response headers */
  readonly headers: HttpHeaders;
  /** HTTP status code */
  readonly status: number;
  /** HTTP status text */
  readonly statusText: string;
  /** Request URL */
  readonly url: string | null;
  /** Whether response indicates success (200-299 status) */
  readonly ok: boolean;
  /** Response type */
  readonly type: HttpEventType.Response | HttpEventType.ResponseHeader;
}

/** HTTP response containing only headers (for HEAD requests) */
export class HttpHeaderResponse extends HttpResponseBase {
  readonly type: HttpEventType.ResponseHeader;
  
  clone(update?: { headers?: HttpHeaders; status?: number; statusText?: string; url?: string }): HttpHeaderResponse;
}

/** HTTP error response */
export class HttpErrorResponse extends HttpResponseBase implements Error {
  readonly name: string;
  readonly message: string;
  readonly error: any | null;
  readonly ok: boolean; // Always false

  constructor(init: HttpErrorResponseInit);
}

Usage Examples:

@Component({
  template: `
    <div *ngIf="loading">Loading...</div>
    <div *ngIf="user">
      <h2>{{ user.name }}</h2>
      <p>Status: {{ responseStatus }}</p>
      <p>Response time: {{ responseTime }}ms</p>
    </div>
    <div *ngIf="error">Error: {{ error.message }}</div>
  `
})
export class UserDetailComponent {
  user: User | null = null;
  loading = false;
  error: HttpErrorResponse | null = null;
  responseStatus: number = 0;
  responseTime: number = 0;

  constructor(private userService: UserService) {}

  loadUser(id: number) {
    this.loading = true;
    this.error = null;
    const startTime = Date.now();

    // Get full response with metadata
    this.userService.getUserWithResponse(id).subscribe({
      next: (response: HttpResponse<User>) => {
        this.user = response.body;
        this.responseStatus = response.status;
        this.responseTime = Date.now() - startTime;
        this.loading = false;

        // Access response headers
        const contentType = response.headers.get('content-type');
        const customHeader = response.headers.get('x-custom-header');
        
        console.log('Response headers:', {
          contentType,
          customHeader,
          etag: response.headers.get('etag')
        });
      },
      error: (error: HttpErrorResponse) => {
        this.error = error;
        this.loading = false;
        
        console.error('HTTP Error:', {
          status: error.status,
          statusText: error.statusText,
          message: error.message,
          error: error.error
        });
      }
    });
  }
}

@Injectable()
export class UserService {
  constructor(private http: HttpClient) {}

  getUserWithResponse(id: number): Observable<HttpResponse<User>> {
    return this.http.get<User>(`/api/users/${id}`, { observe: 'response' });
  }

  createUserRequest(userData: any): HttpRequest<any> {
    return new HttpRequest('POST', '/api/users', userData, {
      headers: new HttpHeaders({
        'Content-Type': 'application/json',
        'X-Requested-With': 'Angular'
      }),
      reportProgress: true
    });
  }
}

HTTP Headers and Parameters

HttpHeaders - Header Management

Immutable container for HTTP headers with fluent API.

/**
 * Immutable set of HTTP headers with fluent API for manipulation
 * Supports case-insensitive header names and multiple values per header
 */
export class HttpHeaders {
  constructor(headers?: string | { [name: string]: string | string[] });

  /** Check if header exists */
  has(name: string): boolean;

  /** Get first value of header */
  get(name: string): string | null;

  /** Get all header names */
  keys(): string[];

  /** Get all values for header */
  getAll(name: string): string[] | null;

  /** Add header value (keeps existing values) */
  append(name: string, value: string | string[]): HttpHeaders;

  /** Set header value (replaces existing values) */
  set(name: string, value: string | string[]): HttpHeaders;

  /** Remove header or specific value */
  delete(name: string, value?: string | string[]): HttpHeaders;

  /** Serialize headers for network transmission */
  forEach(fn: (name: string, values: string[]) => void): void;
}

HttpParams - URL Parameter Management

Immutable container for URL parameters with fluent API.

/**
 * Immutable set of URL parameters with fluent API for manipulation
 * Handles URL encoding and multiple values per parameter
 */
export class HttpParams {
  constructor(options?: HttpParamsOptions);

  /** Check if parameter exists */
  has(param: string): boolean;

  /** Get first value of parameter */
  get(param: string): string | null;

  /** Get all values for parameter */
  getAll(param: string): string[] | null;

  /** Get all parameter names */
  keys(): string[];

  /** Add parameter value (keeps existing values) */
  append(param: string, value: string | number | boolean): HttpParams;

  /** Add multiple parameters from object */
  appendAll(params: { [param: string]: string | number | boolean | ReadonlyArray<string | number | boolean> }): HttpParams;

  /** Set parameter value (replaces existing values) */
  set(param: string, value: string | number | boolean): HttpParams;

  /** Remove parameter or specific value */
  delete(param: string, value?: string | number | boolean): HttpParams;

  /** Serialize parameters to query string */
  toString(): string;
}

/** Options for HttpParams constructor */
interface HttpParamsOptions {
  fromString?: string;
  fromObject?: { [param: string]: string | number | boolean | ReadonlyArray<string | number | boolean> };
  encoder?: HttpParameterCodec;
}

/** Interface for custom parameter encoding */
interface HttpParameterCodec {
  encodeKey(key: string): string;
  encodeValue(value: string): string;
  decodeKey(key: string): string;
  decodeValue(value: string): string;
}

/** Default URL encoding implementation */
export class HttpUrlEncodingCodec implements HttpParameterCodec {
  encodeKey(key: string): string;
  encodeValue(value: string): string;
  decodeKey(key: string): string;
  decodeValue(value: string): string;
}

Usage Examples:

@Injectable()
export class ApiService {
  constructor(private http: HttpClient) {}

  // Working with headers
  createAuthenticatedRequest<T>(url: string): Observable<T> {
    const headers = new HttpHeaders()
      .set('Authorization', `Bearer ${this.getToken()}`)
      .set('Content-Type', 'application/json')
      .set('Accept', 'application/json')
      .append('X-Custom-Header', 'value1')
      .append('X-Custom-Header', 'value2'); // Multiple values

    return this.http.get<T>(url, { headers });
  }

  // Working with parameters
  searchUsers(criteria: SearchCriteria): Observable<User[]> {
    let params = new HttpParams()
      .set('query', criteria.query)
      .set('page', criteria.page.toString())
      .set('limit', criteria.limit.toString());

    // Conditional parameters
    if (criteria.role) {
      params = params.set('role', criteria.role);
    }

    if (criteria.tags && criteria.tags.length > 0) {
      // Multiple values for same parameter
      criteria.tags.forEach(tag => {
        params = params.append('tags', tag);
      });
    }

    return this.http.get<User[]>('/api/users/search', { params });
  }

  // Parameters from object
  getFilteredData(filters: any): Observable<any[]> {
    const params = new HttpParams({ fromObject: filters });
    return this.http.get<any[]>('/api/data', { params });
  }

  // Parameters from query string
  parseUrlParams(queryString: string): HttpParams {
    return new HttpParams({ fromString: queryString });
  }

  // Custom encoding
  getWithCustomEncoding(): Observable<any> {
    const customEncoder: HttpParameterCodec = {
      encodeKey: (key: string) => encodeURIComponent(key),
      encodeValue: (value: string) => encodeURIComponent(value),
      decodeKey: (key: string) => decodeURIComponent(key),
      decodeValue: (value: string) => decodeURIComponent(value)
    };

    const params = new HttpParams({ 
      fromObject: { 'special chars': 'hello world!' },
      encoder: customEncoder 
    });

    return this.http.get('/api/encoded', { params });
  }

  private getToken(): string {
    return localStorage.getItem('auth_token') || '';
  }
}

@Component({})
export class HeaderInspectorComponent {
  checkHeaders() {
    const headers = new HttpHeaders({
      'Content-Type': 'application/json',
      'X-Multi-Value': ['value1', 'value2']
    });

    console.log('Has Content-Type:', headers.has('content-type')); // true (case insensitive)
    console.log('Content-Type:', headers.get('Content-Type'));
    console.log('All X-Multi-Value:', headers.getAll('X-Multi-Value'));
    console.log('All header names:', headers.keys());

    // Iterate over all headers
    headers.forEach((name, values) => {
      console.log(`${name}: ${values.join(', ')}`);
    });
  }
}

HTTP Context and Interceptors

HttpContext - Request Context

Type-safe context for passing data through HTTP interceptors.

/**
 * Type-safe context store for HTTP requests
 * Allows passing data through interceptor chain
 */
export class HttpContext {
  /** Set context value for token */
  set<T>(token: HttpContextToken<T>, value: T): HttpContext;

  /** Get context value for token */
  get<T>(token: HttpContextToken<T>): T;

  /** Delete context value for token */
  delete<T>(token: HttpContextToken<T>): HttpContext;

  /** Check if context has value for token */
  has<T>(token: HttpContextToken<T>): boolean;

  /** Get all context token keys */
  keys(): IterableIterator<HttpContextToken<unknown>>;
}

/**
 * Token for type-safe context values
 * Acts as both key and type information
 */
export class HttpContextToken<T> {
  constructor(public readonly defaultValue: () => T);
}

HTTP Interceptors

Intercept and modify HTTP requests and responses.

/**
 * Interface for HTTP interceptors (class-based)
 */
export interface HttpInterceptor {
  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>;
}

/**
 * Function-based HTTP interceptor
 */
export type HttpInterceptorFn = (req: HttpRequest<unknown>, next: HttpHandlerFn) => Observable<HttpEvent<unknown>>;

/**
 * Function signature for next handler in interceptor chain
 */
export type HttpHandlerFn = (req: HttpRequest<unknown>) => Observable<HttpEvent<unknown>>;

/**
 * Abstract base class for HTTP handlers
 */
export abstract class HttpHandler {
  abstract handle(req: HttpRequest<any>): Observable<HttpEvent<any>>;
}

/**
 * HTTP backend interface
 */
export abstract class HttpBackend implements HttpHandler {
  abstract handle(req: HttpRequest<any>): Observable<HttpEvent<any>>;
}

/** Injection token for HTTP interceptors */
export const HTTP_INTERCEPTORS: InjectionToken<HttpInterceptor[]>;

Usage Examples:

// Context usage
const IS_CACHE_ENABLED = new HttpContextToken<boolean>(() => true);
const RETRY_COUNT = new HttpContextToken<number>(() => 3);

@Injectable()
export class ApiService {
  constructor(private http: HttpClient) {}

  getCachedData(): Observable<any> {
    const context = new HttpContext()
      .set(IS_CACHE_ENABLED, true)
      .set(RETRY_COUNT, 5);

    return this.http.get('/api/data', { context });
  }

  getNonCachedData(): Observable<any> {
    const context = new HttpContext().set(IS_CACHE_ENABLED, false);
    return this.http.get('/api/fresh-data', { context });
  }
}

// Function-based interceptor
export const authInterceptor: HttpInterceptorFn = (req, next) => {
  const authService = inject(AuthService);
  const token = authService.getToken();

  if (token) {
    const authReq = req.clone({
      headers: req.headers.set('Authorization', `Bearer ${token}`)
    });
    return next(authReq);
  }

  return next(req);
};

// Class-based interceptor
@Injectable()
export class LoggingInterceptor implements HttpInterceptor {
  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const startTime = Date.now();
    
    console.log(`[HTTP] ${req.method} ${req.url}`);

    return next.handle(req).pipe(
      tap(event => {
        if (event.type === HttpEventType.Response) {
          const duration = Date.now() - startTime;
          console.log(`[HTTP] ${req.method} ${req.url} - ${event.status} (${duration}ms)`);
        }
      }),
      catchError(error => {
        const duration = Date.now() - startTime;
        console.error(`[HTTP] ${req.method} ${req.url} - ERROR (${duration}ms)`, error);
        return throwError(() => error);
      })
    );
  }
}

// Caching interceptor using context
@Injectable()
export class CacheInterceptor implements HttpInterceptor {
  private cache = new Map<string, HttpResponse<any>>();

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    // Check if caching is enabled for this request
    if (!req.context.get(IS_CACHE_ENABLED) || req.method !== 'GET') {
      return next.handle(req);
    }

    const cacheKey = req.urlWithParams;
    const cached = this.cache.get(cacheKey);

    if (cached) {
      console.log('Cache hit:', cacheKey);
      return of(cached);
    }

    return next.handle(req).pipe(
      filter(event => event.type === HttpEventType.Response),
      tap(event => {
        if (event instanceof HttpResponse) {
          this.cache.set(cacheKey, event);
          console.log('Cached response:', cacheKey);
        }
      })
    );
  }
}

// Provider configuration
@NgModule({
  providers: [
    // Function-based interceptors
    provideHttpClient(
      withInterceptors([authInterceptor, loggingInterceptor])
    ),
    
    // Or class-based interceptors
    {
      provide: HTTP_INTERCEPTORS,
      useClass: LoggingInterceptor,
      multi: true
    },
    {
      provide: HTTP_INTERCEPTORS,
      useClass: CacheInterceptor,
      multi: true
    }
  ]
})
export class AppModule {}

HTTP Events and Status

HTTP Events

Events emitted during HTTP request lifecycle.

/** Types of HTTP events */
export enum HttpEventType {
  Sent = 0,
  UploadProgress = 1,
  ResponseHeader = 2,
  DownloadProgress = 3,
  Response = 4,
  User = 5
}

/** Union type for all HTTP events */
export type HttpEvent<T> = 
  | HttpSentEvent 
  | HttpHeaderResponse 
  | HttpResponse<T> 
  | HttpProgressEvent 
  | HttpUserEvent<T>;

/** Event indicating request was sent */
export interface HttpSentEvent {
  type: HttpEventType.Sent;
}

/** Base interface for progress events */
export interface HttpProgressEvent {
  type: HttpEventType.DownloadProgress | HttpEventType.UploadProgress;
  loaded: number;
  total?: number;
}

/** Download progress event */
export interface HttpDownloadProgressEvent extends HttpProgressEvent {
  type: HttpEventType.DownloadProgress;
  partialText?: string;
}

/** Upload progress event */
export interface HttpUploadProgressEvent extends HttpProgressEvent {
  type: HttpEventType.UploadProgress;
}

/** Custom user event */
export interface HttpUserEvent<T> {
  type: HttpEventType.User;
}

HTTP Status Codes

Comprehensive enumeration of HTTP status codes.

/** Standard HTTP status codes */
export enum HttpStatusCode {
  Continue = 100,
  SwitchingProtocols = 101,
  Processing = 102,
  EarlyHints = 103,

  Ok = 200,
  Created = 201,
  Accepted = 202,
  NonAuthoritativeInformation = 203,
  NoContent = 204,
  ResetContent = 205,
  PartialContent = 206,
  MultiStatus = 207,
  AlreadyReported = 208,
  ImUsed = 226,

  MultipleChoices = 300,
  MovedPermanently = 301,
  Found = 302,
  SeeOther = 303,
  NotModified = 304,
  UseProxy = 305,
  Unused = 306,
  TemporaryRedirect = 307,
  PermanentRedirect = 308,

  BadRequest = 400,
  Unauthorized = 401,
  PaymentRequired = 402,
  Forbidden = 403,
  NotFound = 404,
  MethodNotAllowed = 405,
  NotAcceptable = 406,
  ProxyAuthenticationRequired = 407,
  RequestTimeout = 408,
  Conflict = 409,
  Gone = 410,
  LengthRequired = 411,
  PreconditionFailed = 412,
  PayloadTooLarge = 413,
  UriTooLong = 414,
  UnsupportedMediaType = 415,
  RangeNotSatisfiable = 416,
  ExpectationFailed = 417,
  ImATeapot = 418,
  MisdirectedRequest = 421,
  UnprocessableEntity = 422,
  Locked = 423,
  FailedDependency = 424,
  TooEarly = 425,
  UpgradeRequired = 426,
  PreconditionRequired = 428,
  TooManyRequests = 429,
  RequestHeaderFieldsTooLarge = 431,
  UnavailableForLegalReasons = 451,

  InternalServerError = 500,
  NotImplemented = 501,
  BadGateway = 502,
  ServiceUnavailable = 503,
  GatewayTimeout = 504,
  HttpVersionNotSupported = 505,
  VariantAlsoNegotiates = 506,
  InsufficientStorage = 507,
  LoopDetected = 508,
  NotExtended = 510,
  NetworkAuthenticationRequired = 511
}

HTTP Client Configuration

Modules and Providers

Configuration modules and providers for HTTP client.

/** Main HTTP client module */
export class HttpClientModule {
  static forRoot(): ModuleWithProviders<HttpClientModule>;
}

/** JSONP support module */
export class HttpClientJsonpModule {}

/** XSRF protection module */
export class HttpClientXsrfModule {
  static withOptions(options: HttpClientXsrfOptions): ModuleWithProviders<HttpClientXsrfModule>;
}

/** Provider function for HTTP client with features */
export function provideHttpClient(...features: HttpFeature<HttpFeatureKind>[]): EnvironmentProviders;

/** HTTP feature types */
export enum HttpFeatureKind {
  Interceptors,
  LegacyInterceptors,
  CustomXsrfConfiguration, 
  NoXsrfProtection,
  JsonpSupport,
  RequestsMadeViaParent,
  Fetch
}

/** Feature configuration functions */
export function withInterceptors(interceptorFns: HttpInterceptorFn[]): HttpFeature<HttpFeatureKind.Interceptors>;
export function withInterceptorsFromDi(): HttpFeature<HttpFeatureKind.LegacyInterceptors>;
export function withXsrfConfiguration(options: HttpClientXsrfOptions): HttpFeature<HttpFeatureKind.CustomXsrfConfiguration>;
export function withNoXsrfProtection(): HttpFeature<HttpFeatureKind.NoXsrfProtection>;
export function withJsonpSupport(): HttpFeature<HttpFeatureKind.JsonpSupport>;
export function withRequestsMadeViaParent(): HttpFeature<HttpFeatureKind.RequestsMadeViaParent>;
export function withFetch(): HttpFeature<HttpFeatureKind.Fetch>;

Usage Examples:

// Progress tracking
@Component({
  template: `
    <div *ngIf="uploadProgress !== null">
      <div class="progress-bar">
        <div [style.width.%]="uploadProgress"></div>
      </div>
      <p>{{ uploadProgress }}% uploaded</p>
    </div>
  `
})
export class FileUploadComponent {
  uploadProgress: number | null = null;

  constructor(private http: HttpClient) {}

  uploadFile(file: File) {
    const formData = new FormData();
    formData.append('file', file);

    this.http.post('/api/upload', formData, {
      reportProgress: true,
      observe: 'events'
    }).subscribe(event => {
      switch (event.type) {
        case HttpEventType.Sent:
          console.log('Request sent');
          break;
        case HttpEventType.UploadProgress:
          if (event.total) {
            this.uploadProgress = Math.round(100 * event.loaded / event.total);
          }
          break;
        case HttpEventType.Response:
          console.log('Upload complete', event.body);
          this.uploadProgress = null;
          break;
      }
    });
  }
}

// Status code handling
@Injectable()
export class ErrorHandlingService {
  handleHttpError(error: HttpErrorResponse): string {
    switch (error.status) {
      case HttpStatusCode.BadRequest:
        return 'Invalid request data';
      case HttpStatusCode.Unauthorized:
        return 'Please log in';
      case HttpStatusCode.Forbidden:
        return 'Access denied';
      case HttpStatusCode.NotFound:
        return 'Resource not found';
      case HttpStatusCode.InternalServerError:
        return 'Server error occurred';
      default:
        return `HTTP Error ${error.status}: ${error.statusText}`;
    }
  }
}

// Modern provider configuration
bootstrapApplication(AppComponent, {
  providers: [
    provideHttpClient(
      withInterceptors([authInterceptor, loggingInterceptor]),
      withFetch(), // Use Fetch API instead of XMLHttpRequest
      withJsonpSupport(), // Enable JSONP
      withXsrfConfiguration({
        cookieName: 'XSRF-TOKEN',
        headerName: 'X-XSRF-TOKEN'
      })
    ),
    // Other providers...
  ]
});