HttpClient: загрузка данных
HttpClient — встроенный в Angular клиент для запросов к серверу. Он сам превращает ответ из JSON в объекты, умеет подставлять заголовки и хорошо работает с тестами. С этого урока мы делаем блог, который читает статьи с тестового API https://jsonplaceholder.typicode.com.
Подключение
Клиент включается в настройках приложения функцией provideHttpClient():
// src/app/app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';
import { provideHttpClient } from '@angular/common/http';
import { routes } from './app.routes';
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes),
provideHttpClient(),
],
};В вашем файле в providers могут быть и другие строки — оставьте их и добавьте provideHttpClient(). В новых версиях Angular клиент может быть доступен и без этой строки, но она понадобится для настроек вроде перехватчиков.
Тип данных
Опишите, как выглядит статья, в файле src/app/post.ts:
// src/app/post.ts
export interface Post {
userId: number;
id: number;
title: string;
body: string;
}Сервис для запросов
Запросы к API удобно держать в сервисе, а не в компонентах:
ng generate service post-api// src/app/post-api.ts
import { Injectable, inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Post } from './post';
@Injectable({ providedIn: 'root' })
export class PostApi {
private http = inject(HttpClient);
private url = 'https://jsonplaceholder.typicode.com/posts';
getPosts() {
return this.http.get<Post[]>(this.url);
}
getPost(id: number) {
return this.http.get<Post>(`${this.url}/${id}`);
}
}Метод get<Post[]>() описывает, какой тип придёт в ответе. Сам запрос он ещё не отправляет — он возвращает Observable, объект «будущего ответа». Запрос уйдёт, когда кто-то на него подпишется.
Вывод в компоненте
ng generate component post-list// src/app/post-list/post-list.ts
import { Component, OnInit, inject, signal } from '@angular/core';
import { PostApi } from '../post-api';
import { Post } from '../post';
@Component({
selector: 'app-post-list',
templateUrl: './post-list.html',
})
export class PostList implements OnInit {
private api = inject(PostApi);
posts = signal<Post[]>([]);
ngOnInit() {
this.api.getPosts().subscribe((posts) => this.posts.set(posts));
}
}<!-- src/app/post-list/post-list.html -->
<h2>Статьи</h2>
@for (post of posts(); track post.id) {
<article>
<h3>{{ post.title }}</h3>
<p>{{ post.body }}</p>
</article>
} @empty {
<p>Загрузка...</p>
}Метод subscribe() отправляет запрос и вызывает функцию, когда придёт ответ. Добавьте <app-post-list /> в src/app/app.html и PostList в imports компонента App — через секунду вместо «Загрузка...» появятся 100 статей. Тексты в этом API на латинском, так задумано.
Частая ошибка
Вызвать this.api.getPosts() без subscribe() и ждать данных. Ничего не произойдёт: на вкладке Network в инструментах разработчика не будет ни одного запроса. Observable из HttpClient ленивый — без подписки запрос не отправляется.