В прошлой теме после отправки запроса в качестве ответа мы получали некоторый объект json, сконструированный на основе пришедших от сервера данных. Например, код отправки данных через запрос POST:
createProduct(product: Product) { return this.http.post(this.url, product); }
В классе компонента мы используем этот метод:
save() { if (this.product.id == null) { this.dataService.createProduct(this.product) .subscribe((data: Product) => this.products.push(data)); } else { this.dataService.updateProduct(this.product) .subscribe(data => this.loadProducts()); } this.cancel(); }
Здесь мы ожидаем, что сервер нам возвратит объект Product - добавленный объект. На стороне сервера этот запрос обрабатывается методом post:
[HttpPost] public IActionResult Post(Product product) { if(ModelState.IsValid) { db.Products.Add(product); db.SaveChanges(); return Ok(product); } return BadRequest(ModelState); }
Таким образом, сервер отправляет объект Product, и на клиенте мы этот объект получаем. Но что если кроме собственно данных мы захотим получить дополнительную информацию о запросе, например, статусный код ответа, заголовки ответа и т.д.? В этом случае на сторое клиента мы можем применять тип HttpResponse, который расположен в пакете @angular/common/http. Этот тип определяет следующие свойства:
body: собственно данные, отправленные сервером
headers: объект HttpHeaders, представляющий коллекцию заголовков ответа
status: числовой код статуса ответа
statusText: текст статуса
ok: возвращает true, если запрос успешно обработан
url: адрес ресурса
Для использования HttpResponse изменим метод createProduct()
в сервисе DataService:
createProduct(product: Product) { return this.http.post(this.url, product, { observe: 'response' }); }
Теперь в компоненте AppComponent получим данные:
import { Component, OnInit } from '@angular/core'; import { DataService } from './data.service'; import { Product } from './product'; import { HttpResponse } from '@angular/common/http'; @Component({ selector: 'app', templateUrl: './app.component.html', providers: [DataService] }) export class AppComponent implements OnInit { product: Product = new Product(); // изменяемый товар products: Product[]; // массив товаров tableMode: boolean = true; // табличный режим constructor(private dataService: DataService) { } ngOnInit() { this.loadProducts(); } loadProducts() { this.dataService.getProducts() .subscribe((data: Product[]) => this.products = data); } save() { if (this.product.id == null) { this.dataService.createProduct(this.product) .subscribe((data: HttpResponse<Product>) => { console.log(data); this.products.push(data.body); }); } else { this.dataService.updateProduct(this.product) .subscribe(data => this.loadProducts()); } this.cancel(); } editProduct(p: Product) { this.product = p; } cancel() { this.product = new Product(); this.tableMode = true; } delete(p: Product) { this.dataService.deleteProduct(p.id) .subscribe(data => this.loadProducts()); } add() { this.cancel(); this.tableMode = false; } }
Теперь полученные данные представляют объект HttpResponse. И поскольку сервер по прежнему посылает объект Product, который был добавлен в БД, то HttpResponse типизрован типом Product:
this.dataService.createProduct(this.product) .subscribe((data: HttpResponse<Product>) => { console.log(data); this.products.push(data.body); });
Через свойство body
можно получить отправленный объект Product. Также можно получить другие данные из HttpResponse.
Добавим новый объект и в консоли браузера мы сможем детально проинспектировать полученный ответ:
И подобным образом мы можем получить другие данные из ответа, например, получим значение заголовка "content-type", который указывает на тип содержимого в ответе:
console.log(data.headers.get("content-type"));