Angular HTTP mijozi


HttpClient ilovangizga HTTP orqali ma’lumotlarni olish va yuborish imkonini beradi.


ULASHISH

HTTP asoslari

  • Mijoz: JSONni olish va yuborish uchun HttpClient-dan foydalaning.
  • Kuzatiladiganlar: HTTP metodlari Kuzatiladiganlarni qaytaradi. subscribe() yoki async pipeline foydalaning.
  • UX: Yuklash va xato xabarlarini tozalash.
  • Bir marta taqdim eting: bootstrap da provideHttpClient() ni ro‘yxatdan o‘tkazing.
import { provideHttpClient, HttpClient } from '@angular/common/http';

// Bootstrap
// bootstrapApplication(App, { providers: [provideHttpClient()] });

// Use in a component
// http.get<User[]>('/api/users').subscribe({ next: d => users = d });

Eslatmalar:

  • Tegishli: HTTP mantiqini inkapsulyatsiya qilish uchun xizmatlar, so‘rovlardan keyin navigatsiya uchun Router va ro‘yxatlar va holatlarni ko‘rsatish uchun shablonlarga qarang.
  • Mijozni bootstrapda provideHttpClient() bilan ta’minlang.
  • Yuklash va xato holatlari bilan bloklanmaydigan UIlardan foydalaning; Ommaviy API-larga chaqirishda CORS (qaysi manbalar API chaqirishini nazorat qiluvchi brauzer xavfsizligi) ga e’tibor bering.
  • Asosiy URL va env: API asosiy URL/konfiguratsiyasini token yoki konstantada markazlashtiring va undan xizmatlarda qayta foydalaning.
  • ishonchlilik: ishonchsiz URL qismlarini mustaqil; so‘rovning URL manzillariga to‘g‘ridan-to‘g‘ri foydalanuvchi kiritgan ma’lumotlarini interpolyatsiya qilishdan saqlaning.

GET so‘rovlari

  • http.get<T>() bilan ma’lumotlarni o‘qing.
  • UX uchun loading va error holatini kuzating.
  • Obunadagi component holatini yangilang.
loading = true; error = '';
http.get<User[]>('/api/users').subscribe({
  next: d => { users = d; loading = false; },
  error: () => { error = 'Failed to load'; loading = false; }
});

Misol

import { bootstrapApplication } from '@angular/platform-browser';
import { Component, inject } from '@angular/core';
import { CommonModule } from '@angular/common';
import { provideHttpClient, HttpClient } from '@angular/common/http';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [CommonModule],
  template: `
    <h3>HttpClient</h3>
    <button (click)="load()">Load Users</button>
    <p *ngIf="loading">Loading...</p>
    <p *ngIf="error" style="color:crimson">{{ error }}</p>
    <ul>
      <li *ngFor="let u of users">{{ u.name }} ({{ u.email }})</li>
    </ul>
  `
})
export class App {
  http = inject(HttpClient);
  users: any[] = [];
  loading = false;
  error = '';

  load() {
    this.loading = true;
    this.error = '';
    this.http.get<any[]>('https://jsonplaceholder.typicode.com/users')
      .subscribe({
        next: (data) => { this.users = data; this.loading = false; },
        error: () => { this.error = 'Failed to load users'; this.loading = false; }
      });
  }
}

bootstrapApplication(App, { providers: [provideHttpClient()] });
<app-root></app-root>

Misolni ishga tushirish »

Misol tushuntirildi

  • provide HttpClient(): HttpClient-ni ro‘yxatdan o‘tkazadi, shuning uchun so‘rovlar ishlaydi.
  • inject(HttpClient): mijozni mustaqil komponentda oladi.
  • GET: http.get<any[]>(url) Kuzatiladiganni qaytaradi; subscribe() muvaffaqiyatga users va muvaffaqiyatsizlikka error qo‘yadi.
  • UX bayroqlari: loading va error shablonni boshqaradi (spinner/xabar).

Eslatmalar:

  • Mustaqil ravishda qulay: HttpClientModule import qilish uchun provideHttpClient() dan foydalaning.
  • O‘zaro kesish: autentifikatsiya/ro‘yxatga olish uchun tutqichlardan (har bir so‘rov/javobda hook’lar) foydalaning; tegishli doirada bir marta ro‘yxatdan o‘ting.
  • UX: Yuklash paytida tugmani o‘chirib, bir necha marta bosishdan saqlaning.
  • CORS: Agar so‘rovlar brauzerda muvaffaqiyatsiz bo‘lib, curl’da ishlasa, sabab CORS bo‘lishi mumkin — origin’ingizga ruxsat beruvchi API’lardan yoki proksi-serverdan foydalaning.
  • Yozish va parametrlar: get<MyType>() dan foydalaning va HttpParams / HttpHeaders bilan opsiyalarni yarating.


POST so‘rovlari

  • http.post<T>() yordamida ma’lumotlarni yarating.
  • Takrorlashlarni oldini olish uchun yuborish paytida tugmani o‘chiring.
  • Qaytarilgan natijani yoki xato xabarini ko‘rsating.
loading = true; error = ''; result = null;
http.post<Post>('/api/posts', { title, body }).subscribe({
  next: r => { result = r; loading = false; },
  error: () => { error = 'Failed to create'; loading = false; }
});

Misol

import { bootstrapApplication } from '@angular/platform-browser';
import { Component, inject } from '@angular/core';
import { CommonModule } from '@angular/common';
import { provideHttpClient, HttpClient } from '@angular/common/http';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [CommonModule],
  template: `
    <h3>HttpClient POST</h3>
    <button (click)="createPost()" [disabled]="loading">Create Post</button>
    <p *ngIf="loading">Sending...</p>
    <p *ngIf="error" style="color:crimson">{{ error }}</p>
    <div *ngIf="result">
      <p>Created Post ID: {{ result.id }}</p>
      <p>Title: {{ result.title }}</p>
    </div>
  `
})
export class App {
  http = inject(HttpClient);
  loading = false;
  error = '';
  result: any = null;

  createPost() {
    this.loading = true;
    this.error = '';
    this.result = null;
    this.http.post<any>('https://jsonplaceholder.typicode.com/posts', {
      title: 'foo',
      body: 'bar',
      userId: 1
    }).subscribe({
      next: (res) => { this.result = res; this.loading = false; },
      error: () => { this.error = 'Failed to create post'; this.loading = false; }
    });
  }
}

bootstrapApplication(App, { providers: [provideHttpClient()] });
<app-root></app-root>

Misolni ishga tushirish »

Misol tushuntirildi

  • POST: http.post<T>(url, body) JSON yuboradi va yaratilgan obyektni qaytaradi.
  • Yuborish paytida o‘chirib qo‘yish: Ikki nusxadagi yuborishning oldini olish uchun tugma loading bilan bog‘lanadi.
  • Natija: Muvaffaqiyatli bo‘lganda, qaytarilgan result ko‘rsating; xato bo‘lsa, aniq xabarni ko‘rsating.

Eslatmalar:

  • Kiritilgan ma’lumotlarni tekshiring: server kutayotgan minimal, tekshirilgan ma’lumotlarni (payload) yuboring; maydon xatolarini aniq ko‘rsating.
  • Idempotency: takroriy arizalardan saqlaning; yuborish paytida va agar kerak bo‘lsa, muvaffaqiyatli bo‘lgandan keyin tugmani o‘chirib qo‘ying.
  • Xatolarni hal qilish: Aniq xato xabarini ko‘rsating va foydalanuvchiga qayta urinib ko‘rishga ruxsat bering; UIni yuklash bayrog‘i bilan javob beradi.

Xato bilan ishlash

  • Har doim foydali xabarni ko‘rsating va qayta urinishga ruxsat bering.
  • Check status codes to decide retry vs fail fast.
  • Yuklash bayrog‘i bilan foydalanuvchi interfeysini sezgir saqlang.
error = ''; loading = true;
http.get('/api/data').subscribe({
  next: r => { data = r; loading = false; },
  error: err => { error = `Request failed (status ${'{'}err?.status ?? 'unknown'{}})`; loading = false; }
});

Misol

import { bootstrapApplication } from '@angular/platform-browser';
import { Component, inject } from '@angular/core';
import { CommonModule } from '@angular/common';
import { provideHttpClient, HttpClient, withInterceptors, HttpResponse, HttpErrorResponse, HttpRequest, HttpHandlerFn } from '@angular/common/http';
import { of, throwError } from 'rxjs';

// Fake HTTP interceptor so the demo works without external network calls
function mockHttp(req: HttpRequest<any>, next: HttpHandlerFn) {
  if (req.method === 'GET' && req.url.includes('jsonplaceholder.typicode.com/usersx')) {
    return throwError(() => new HttpErrorResponse({ status: 404, statusText: 'Not Found', url: req.url }));
  }
  if (req.method === 'GET' && req.url.includes('jsonplaceholder.typicode.com/users')) {
    const body = [
      { id: 1, name: 'Leanne Graham', email: 'leanne@example.com' },
      { id: 2, name: 'Ervin Howell', email: 'ervin@example.com' }
    ];
    return of(new HttpResponse({ status: 200, body }));
  }
  return next(req);
}

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [CommonModule],
  styles: [`
    button { margin-right: 8px; }
    .error { color: crimson; }
    .ok { color: seagreen; }
  `],
  template: `
    <h3>HTTP Error Handling</h3>

    <div>
      <button (click)="loadOk()" [disabled]="loading">Load OK</button>
      <button (click)="loadFail()" [disabled]="loading">Load Fail</button>
      <button (click)="retry()" [disabled]="!lastAction || loading">Retry</button>
    </div>

    <p *ngIf="loading">Loading...</p>
    <p *ngIf="error" class="error">{{ error }}</p>
    <p *ngIf="!error && data" class="ok">Loaded {{ isArray(data) ? data.length + ' items' : '1 item' }}</p>

    <ul *ngIf="isArray(data)">
      <li *ngFor="let u of data">{{ u.name }} ({{ u.email }})</li>
    </ul>
  `
})
export class App {
  http = inject(HttpClient);
  loading = false;
  error = '';
  data: any[] | null = null;
  lastAction = '';
  isArray(value: unknown): value is any[] { return Array.isArray(value as any); }

  fetch(url: string): void {
    this.loading = true;
    this.error = '';
    this.data = null;
    this.http.get<any[]>(url).subscribe({
      next: (res) => { this.data = res; this.loading = false; },
      error: (err) => {
        const status = err?.status ?? 'unknown';
        this.error = `Request failed (status ${status}). Please try again.`;
        this.loading = false;
      }
    });
  }

  loadOk() {
    this.lastAction = 'ok';
    this.fetch('https://jsonplaceholder.typicode.com/users');
  }

  loadFail() {
    this.lastAction = 'fail';
    this.fetch('https://jsonplaceholder.typicode.com/usersx');
  }

  retry() {
    if (this.lastAction === 'ok') this.loadOk();
    else if (this.lastAction === 'fail') this.loadFail();
  }
}

bootstrapApplication(App, { providers: [provideHttpClient(withInterceptors([mockHttp]))] });
<app-root></app-root>

Misolni ishga tushirish »

Misol tushuntirildi

  • Xato xabari: err.status dan foydali xabar yarating; UI ni loading bilan javob beradi.
  • Qayta urinish: lastAction-ni saqlang va oxirgi so‘rovni qayta ishga tushirish uchun retry() tugmachasini ulang.
  • OK va muvaffaqiyatsiz: Alohida usullar muvaffaqiyat va muvaffaqiyatsizlik oqimini ko‘rsatishga yordam beradi.

Eslatmalar:

  • Xatolarni yutmang: foydalanuvchilarga foydali xabar yuboring va debug uchun ma’lumotlarni jurnalga kiriting.
  • Qayta urinish strategiyasi: Faqat vaqtinchalik xatolarda qayta urinib ko‘ring (masalan, 5xx); 4xx mijoz xatolarini qayta urinishdan saqlaning.
  • Fikr-mulohaza: Aniq xato xabarini ko‘rsating va foydalanuvchiga qayta urinib ko‘rishga ruxsat bering; UIni yuklash bayrog‘i bilan javob beradi.
  • Eskirgan so‘rovlarni bekor qiling: Tez kiritilganda, poygalardan qochish uchun oxirgi oqimga (masalan, switchMap) o‘ting.
  • Interceptors: autentifikatsiya sarlavhalarini markazlashtiring, jurnalga yozing va komponentlarni nozik saqlash uchun qayta urinib ko‘ring.

HTTP interceptor’lar

  • Har bir so‘rov/javobda o‘zaro mantiqni ishga tushiring (masalan, autentifikatsiya sarlavhalari, jurnallar).
  • provideHttpClient(...) bilan bootstrap-da bir marta ro‘yxatdan o‘ting.
import { HttpInterceptorFn, provideHttpClient, withInterceptors } from '@angular/common/http';

export const authInterceptor: HttpInterceptorFn = (req, next) => {
  const cloned = req.clone({ setHeaders: { Authorization: 'Bearer TOKEN' } });
  return next(cloned);
};

bootstrapApplication(App, {
  providers: [provideHttpClient(withInterceptors([authInterceptor]))]
});

Misol

import { bootstrapApplication } from '@angular/platform-browser';
import { Component } from '@angular/core';
import { provideHttpClient, withInterceptors } from '@angular/common/http';

@Component({ selector: 'app-root', standalone: true, template: `<p>Interceptors demo</p>` })
export class App {}

bootstrapApplication(App, {
  providers: [provideHttpClient(withInterceptors([]))]
});
<app-root></app-root>

Misolni ishga tushirish »

Misol tushuntirildi

  • withInterceptors([...]): Barcha so‘rovlar uchun interceptor funksiyalarini qayd qiladi.
  • Interceptor: (req, next) funksiyasi, so‘rovni o‘zgartirish uchun req.clone(...), keyin esa next(req) ni chaqiradi.
  • provideHttpClient(): HttpClient-ni yoqadi va bootstrap-da tutqichlarni tuzadi.


W3Schools Pathfinder

Yutuqlaringizni kuzating – bu bepul!