Repository: tanstack/query
File: examples/angular/auto-refetching/src/app/interceptor/mock-api.interceptor.ts (TypeScript)

Code before:
/**
 * MockApiInterceptor is used to simulate API responses for `/api/tasks` endpoints.
 * It handles the following operations:
 * - GET: Fetches all tasks from localStorage.
 * - POST: Adds a new task to localStorage.
 * - DELETE: Clears all tasks from localStorage.
 * Simulated responses include a delay to mimic network latency.
 */
import { Injectable } from '@angular/core'
import { HttpResponse } from '@angular/common/http'
import { delay, of } from 'rxjs'
import type {
  HttpEvent,
  HttpHandler,
  HttpInterceptor,
  HttpRequest,
} from '@angular/common/http'
import type { Observable } from 'rxjs'

@Injectable()
export class MockApiInterceptor implements HttpInterceptor {
  intercept(
    req: HttpRequest<any>,
    next: HttpHandler,
  ): Observable<HttpEvent<any>> {
    if (req.url === '/api/tasks') {
      switch (req.method) {
        case 'GET':
          return this.respondWith(
            200,
            JSON.parse(localStorage.getItem('tasks') || '[]'),
          ).pipe(delay(100))
        case 'POST':
          const tasks = JSON.parse(localStorage.getItem('tasks') || '[]')
          tasks.push(req.body)
          localStorage.setItem('tasks', JSON.stringify(tasks))
          return this.respondWith(201, {
            status: 'success',
            task: req.body,
          }).pipe(delay(100))
        case 'DELETE':
          localStorage.removeItem('tasks')
          return this.respondWith(200, { status: 'success' }).pipe(delay(100))
      }
    }
    return next.handle(req)

Review comment (suggestion):
Angular documentation recommends functional interceptors

> Prefer [withInterceptors](https://angular.dev/api/common/http/withInterceptors) and functional interceptors instead, as support for DI-provided interceptors may be phased out in a later release.

Code after:
/**
 * MockApiInterceptor is used to simulate API responses for `/api/tasks` endpoints.
 * It handles the following operations:
 * - GET: Fetches all tasks from localStorage.
 * - POST: Adds a new task to localStorage.
 * - DELETE: Clears all tasks from localStorage.
 * Simulated responses include a delay to mimic network latency.
 */
import { HttpResponse } from '@angular/common/http'
import { delay, of } from 'rxjs'
import type {
  HttpEvent,
  HttpHandlerFn,
  HttpInterceptorFn,
  HttpRequest,
} from '@angular/common/http'
import type { Observable } from 'rxjs'

export const mockInterceptor: HttpInterceptorFn = (
  req: HttpRequest<unknown>,
  next: HttpHandlerFn,
): Observable<HttpEvent<any>> => {
  const respondWith = (status: number, body: any) =>
    of(new HttpResponse({ status, body })).pipe(delay(100))
  if (req.url === '/api/tasks') {
    switch (req.method) {
      case 'GET':
        return respondWith(
          200,
          JSON.parse(localStorage.getItem('tasks') || '[]'),
        )
      case 'POST':
        const tasks = JSON.parse(localStorage.getItem('tasks') || '[]')
        tasks.push(req.body)
        localStorage.setItem('tasks', JSON.stringify(tasks))
        return respondWith(201, {
          status: 'success',
          task: req.body,
        })
      case 'DELETE':
        localStorage.removeItem('tasks')
        return respondWith(200, { status: 'success' })
    }
  }
  return next(req)
}