Skip to main content
Angular Basics
CHAPTER 14 Beginner

Angular HTTP Client and APIs

Updated: May 18, 2026
5 min read

# CHAPTER 14

Angular HTTP Client and APIs

1. Chapter Introduction

Real applications consume data from servers. Angular's HttpClient module provides a clean, Observable-based API for making HTTP requests. When combined with services and RxJS, it becomes a powerful data layer that seamlessly integrates into your component architecture.

2. Learning Objectives

  • Set up HttpClient in an Angular application.
  • Make GET, POST, PUT, and DELETE requests.
  • Handle HTTP errors gracefully using catchError.
  • Use TypeScript interfaces to type API responses.
  • Build a Weather Application.

3. Setting Up HttpClient

app.config.ts
12345678
import { provideHttpClient } from '@angular/common/http';

export const appConfig = {
  providers: [
    provideRouter(routes),
    provideHttpClient()  // Register HttpClient provider
  ]
};

4. Making a GET Request

weather.service.ts
1234567891011121314151617181920212223
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

interface WeatherData {
  name: string;
  main: { temp: number; humidity: number };
  weather: Array<{ description: string }>;
}

@Injectable({ providedIn: &#039;root&#039; })
export class WeatherService {
  private apiKey = &#039;YOUR_API_KEY&#039;;
  private baseUrl = &#039;https://api.openweathermap.org/data/2.5';

  constructor(private http: HttpClient) {}

  getWeather(city: string): Observable<WeatherData> {
    return this.http.get<WeatherData>(
      `${this.baseUrl}/weather?q=${city}&appid=${this.apiKey}&units=metric`
    );
  }
}
weather.component.ts
1234567891011121314151617181920212223242526272829
import { Component } from &#039;@angular/core&#039;;
import { WeatherService } from &#039;../weather.service&#039;;

@Component({
  selector: &#039;app-weather&#039;,
  templateUrl: &#039;./weather.component.html&#039;
})
export class WeatherComponent {
  city: string = &#039;&#039;;
  weather: any = null;
  loading: boolean = false;
  errorMessage: string = &#039;&#039;;

  constructor(private weatherService: WeatherService) {}

  search(): void {
    this.loading = true;
    this.weatherService.getWeather(this.city).subscribe({
      next: (data) => {
        this.weather = data;
        this.loading = false;
      },
      error: (err) => {
        this.errorMessage = &#039;City not found. Try again!&#039;;
        this.loading = false;
      }
    });
  }
}
html
123456789101112
<input [(ngModel)]="city" placeholder="Enter city name" />
<button (click)="search()">Search</button>

<div *ngIf="loading">⏳ Loading...</div>
<div *ngIf="errorMessage">❌ {{ errorMessage }}</div>

<div *ngIf="weather">
  <h2>{{ weather.name }}</h2>
  <p>🌡️ {{ weather.main.temp }}°C</p>
  <p>💧 Humidity: {{ weather.main.humidity }}%</p>
  <p>{{ weather.weather[0].description | titlecase }}</p>
</div>

5. POST, PUT, DELETE Requests

typescript
1234567891011121314151617181920
// CRUD operations in a service
export class ProductService {
  private apiUrl = &#039;https://api.example.com/products';
  constructor(private http: HttpClient) {}

  // POST - Create
  createProduct(product: any): Observable<any> {
    return this.http.post(this.apiUrl, product);
  }

  // PUT - Update
  updateProduct(id: number, product: any): Observable<any> {
    return this.http.put(`${this.apiUrl}/${id}`, product);
  }

  // DELETE - Remove
  deleteProduct(id: number): Observable<any> {
    return this.http.delete(`${this.apiUrl}/${id}`);
  }
}

6. Error Handling with catchError

typescript
12345678910111213
import { catchError, throwError } from &#039;rxjs&#039;;

getWeather(city: string): Observable<WeatherData> {
  return this.http.get<WeatherData>(`${this.baseUrl}?q=${city}`)
    .pipe(
      catchError(error => {
        if (error.status === 404) {
          return throwError(() => new Error(&#039;City not found&#039;));
        }
        return throwError(() => new Error(&#039;Server error, please try later&#039;));
      })
    );
}

7. HTTP Headers and Auth Tokens

typescript
123456789
import { HttpHeaders } from &#039;@angular/common/http&#039;;

getProtectedData(): Observable<any> {
  const headers = new HttpHeaders({
    &#039;Authorization&#039;: `Bearer ${localStorage.getItem(&#039;token&#039;)}`,
    &#039;Content-Type&#039;: &#039;application/json&#039;
  });
  return this.http.get(&#039;/api/protected&#039;, { headers });
}

8. Common Mistakes

  • Subscribing in the service instead of the component: Services should return Observables, not subscribe to them. Components decide when to subscribe.
  • Not unsubscribing: Always unsubscribe from HTTP Observables in ngOnDestroy or use the async pipe to handle subscriptions automatically.

9. MCQs with Answers

Question 1

What Angular module provides the HttpClient service?

Question 2

What does http.get<WeatherData>(url) return?

Question 3

What method is called on an Observable to start receiving data?

Question 4

In the .subscribe() method, what callback handles success?

Question 5

In the .subscribe() method, what callback handles errors?

Question 6

Which RxJS operator is used to catch and handle HTTP errors in a pipe?

Question 7

Which HTTP method is used to CREATE a new resource?

Question 8

Which HTTP method is used to completely REPLACE an existing resource?

Question 9

How do you add an Authorization header to an HTTP request?

Question 10

Why should API calls be made in Services rather than directly in components?

10. Interview Questions

  • Q: What is the difference between a Promise and an Observable? Why does Angular's HttpClient use Observables?
  • Q: How would you retry a failed HTTP request 3 times before showing an error?

11. Summary

Angular's HttpClient paired with RxJS Observables creates a declarative, powerful, and testable data layer. By keeping all HTTP calls inside services and using catchError for graceful error handling, Angular applications stay robust and user-friendly even when the network misbehaves.

12. Next Chapter Recommendation

Every Angular component has a life — it is created, updated, and destroyed. In Chapter 15: Angular Lifecycle Hooks, we will learn how to hook into these moments to fetch data at the right time, clean up subscriptions, and respond to input changes.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·