HttpClient и отправка запросов¶
Для взаимодействия с сервером и отправки запросов по протоколу HTTP применяется класс HttpClient
. Этот класс определяет ряд методов для отправки различного рода запросов: GET
, POST
, PUT
, DELETE
. Данный класс построен поверх стандартного объекта в JavaScript — XMLHttpRequest
.
Для использования этого класса в проект необходимо установить пакет @angular/common
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
И также в файле модуля AppModule
должен быть импортирован класс HttpClientModule
из пакета @angular/common/http
:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Стоит отметить, что в предыдущих версиях Angular (2,4) использовался для взаимодействия с сетью тип HttpModule
из пакета @angular/http
. Начиная с версии Angular 5 тип HttpModule
и вообще пакет @angular/http
являются устаревшими, поэтому рекомендуется применять именно классы HttpClient
и HttpClientModule
, которые собственно и используются в данном руководстве.
Вначале рассмотрим выполнение простейших GET-запросов. Пусть у нас есть стандартная структура проекта:
В корневую папку проекта добавим файл user.json
, который будет представлять данные:
1 2 3 4 |
|
Для представления данных в папку src/app
добавим новый файл user.ts
и определим в нем следующий код:
1 2 3 4 |
|
Для оправки запроса определим в компоненте AppComponent
следуюший код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|
В данном случае в шаблоне выводятся данные объекта User
, которые мы хотим получить с сервера. Однако загрузка данных, скажем, в конструкторе компонента не очень желательна. В этом плане метод ngOnInit()
, который определен в интерфейсе OnInit
и который вызывается при инициализации компонента представляет более предпочтительное место для загрузки данных. В конструкторе же мы просто получаем сервис HttpClient
.
Далее в методе ngOnInit()
получаем данные из сервиса. Сам метод http.get()
возвращает объект Observable<any>
. Observable
представляет своего рода поток, и для прослушивания событий из этого потока применяется метод subscribe
. Этот метод определяет действие над результатом запроса — полученными с сервера данными. В данном случае действие определено в виде стрелочной функции. Причем поскольку между схемой класса User
и данными из файла json
есть прямое сопоставление, то получаемые данные мы можем определить как объект User
, и присвоить их переменной данного класса:
1 |
|
В итоге при запуске веб-страницы мы увидим загруженные данные из файла user.json
.
Создание сервиса¶
При взаимодействии с сервером, как правило, обращения к серверу происходят не непосредственно из компонента, а из вспомогательных сервисов. Поскольку сервис может определять дополнительную логику обработки полученных с сервера данных, которую могли бы сделать код компонента перегруженным. Кроме того, сервисы могут определять функционал, который будет использоваться несколькими компонентами. Компоненты же выступают в качестве потребителей данных, которые получены от сервисов.
Поэтому для работы с http
добавим в папку src/app
новый файл http.service.ts
со следующим содержимым:
1 2 3 4 5 6 7 8 9 10 11 |
|
Для отправки запросов сервис получает объект HttpClient
. Чтобы данный сервис также могли использовать и другие компонетны через механизм dependency injection, к классу применяется декоратор @Injectable
.
Для выполнения get-запроса у объекта HttpClient
вызывается метод get()
, в который передается адрес запроса — в нашем случае json-файл с данными.
В итоге структура проекта будет выглядеть следующим образом:
Теперь используем этот сервис в компоненте AppComponent
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
|
Загрузка сложных данных¶
В примерах выше определение json-файла соответствует определению класса User
, поэтому простое присвоение this.user=data
пройдет успешно. И подобным образом мы можем загружать и другие более сложные данные. Например, определим в корневой папке проекта файл users.json
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
Изменим в классе HttpService
адрес загрузки данных:
1 2 3 |
|
И изменим код компонента:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
|
В данном случае мы хотим получить массив объектов User
. Но напрямую данные из users.json
не соответствуют массиву. Массив в файле определен по ключу userList
. Поэтому, используя данный ключ, мы достаем нужные данные из ответа сервера: this.users=data["userList"]
.