Angular 20 Resource API, httpResource Ñа пиÑÐ°Ð½Ð½Ñ Ð´Ð»Ñ ÑÐµÑ Ð½ÑÑÐ½Ð¸Ñ ÑпÑвбеÑÑд
ÐеÑалÑний поÑÑбник з Resource API в Angular 20: resource(), rxResource() Ñа httpResource() Ð´Ð»Ñ ÑеакÑивного оÑÑÐ¸Ð¼Ð°Ð½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ . ÐалÑдаÑÑÑ Zod, ÑÑÐ´ÐºÐ¾Ð²Ñ ÑÑаÑÑÑи, мÑгÑаÑÑÑ Ð· HttpClient Ñа акÑÑалÑÐ½Ñ Ð¿Ð¸ÑÐ°Ð½Ð½Ñ Ð´Ð»Ñ ÑÐµÑ Ð½ÑÑÐ½Ð¸Ñ ÑпÑвбеÑÑд Angular Ñ 2026 ÑоÑÑ.

Angular 20 пеÑеÑвоÑив Resource API з екÑпеÑименÑалÑÐ½Ð¾Ñ ÑÑнкÑÑоналÑноÑÑÑ Ð½Ð° ÑÑабÑлÑний пÑимÑÑив ÑÑеймвоÑкÑ. ÐабÑÑ ÑнÑÑÑÑменÑÑв resource(), rxResource() Ñа httpResource() Ð½Ð°Ð´Ð°Ñ ÑозÑобникам деклаÑаÑÐ¸Ð²Ð½Ñ Ð¼Ð¾Ð´ÐµÐ»Ñ Ð´Ð»Ñ Ð·Ð°Ð²Ð°Ð½ÑаженнÑ, вÑдÑÑÐµÐ¶ÐµÐ½Ð½Ñ Ñа ÑнвалÑдаÑÑÑ Ð°ÑинÑ
ÑонниÑ
даниÑ
, ÑÑÑно ÑнÑегÑÐ¾Ð²Ð°Ð½Ñ Ñз ÑиÑÑÐµÐ¼Ð¾Ñ ÑигналÑв Angular. Ð¦Ñ Ð¿ÑимÑÑиви ÑÑÑваÑÑÑ Ð½ÐµÐ¾Ð±Ñ
ÑднÑÑÑÑ ÑÑÑного кеÑÑÐ²Ð°Ð½Ð½Ñ Ð¿ÑдпиÑками, пÑапоÑÑÑми ÑÑÐ°Ð½Ñ Ð·Ð°Ð²Ð°Ð½ÑÐ°Ð¶ÐµÐ½Ð½Ñ Ñа Ñ
Ñками жиÑÑÑвого ÑÐ¸ÐºÐ»Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½ÑÑв â клаÑиÑними джеÑелами Ð²Ð¸Ð¿Ð°Ð´ÐºÐ¾Ð²Ð¾Ñ ÑкладноÑÑÑ Ð² Angular-заÑÑоÑÑнкаÑ
.
У ÑÑаÑÑÑ Ð´ÐµÑалÑно ÑозглÑдаÑÑÑÑÑ ÑÑи ваÑÑанÑи Resource API, пÑодемонÑÑÑовано пÑакÑиÑÐ½Ñ ÑÑенаÑÑÑ Ð· пÑикладами кодÑ, опиÑано пÑÐ´Ñ Ñд до валÑдаÑÑÑ Ð²ÑдповÑдей ÑеÑвеÑа ÑеÑез Zod Ñа зÑбÑано пиÑаннÑ, Ñо найÑаÑÑÑÑе зÑÑÑÑÑÑаÑÑÑÑÑ Ð½Ð° ÑÐµÑ Ð½ÑÑÐ½Ð¸Ñ ÑпÑвбеÑÑÐ´Ð°Ñ Angular Ñ 2026 ÑоÑÑ.
Resource API вийÑов Ð·Ñ ÑÑадÑÑ developer preview Ñа оÑÑимав ÑÑабÑлÑний ÑÑаÑÑÑ. ÐÐ¾Ð»Ð¾Ð²Ð½Ñ Ð·Ð¼Ñни ÑÑоÑÑÑÑÑÑÑ API: паÑамеÑÑ request пеÑейменовано на params, а ÑÑнкÑÑÑ loader Ñа stream замÑнили попеÑÐµÐ´Ð½Ñ Ð½Ð°Ð·Ð²Ð¸ Ñ ÐºÐ¾Ð½ÑÑакÑаÑ
resource() Ñа rxResource(). ÐÑÑм Ñого, httpResource пÑдÑÑимÑÑ Ð½Ð°ÑÐ¸Ð²Ð½Ñ Ð²Ð°Ð»ÑдаÑÑÑ ÑеÑез опÑÑÑ parse, а Ñип ResourceStatus ÑÐµÐ¿ÐµÑ Ð²Ð¸ÐºÐ¾ÑиÑÑовÑÑ ÑÑÐ´ÐºÐ¾Ð²Ñ Ð»ÑÑеÑали ('loading', 'resolved', 'error') замÑÑÑÑ ÑиÑлового enum. СеманÑика залиÑаÑÑÑÑÑ Ð½ÐµÐ·Ð¼ÑнноÑ, пÑоÑе ÑинÑакÑÐ¸Ñ Ð¿Ð¾ÑÑебÑÑ Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¿Ñи пеÑеÑ
Ð¾Ð´Ñ Ð· Angular 19.
ТÑи ваÑÑанÑи Resource API: resource, rxResource Ñа httpResource
Resource API в Angular 20 ÑкладаÑÑÑÑÑ Ð· ÑÑÑÐ¾Ñ Ð¾ÐºÑÐµÐ¼Ð¸Ñ Ð¿ÑимÑÑивÑв, кожен Ñз ÑÐºÐ¸Ñ ÑозÑÐ°Ñ Ð¾Ð²Ð°Ð½Ð¸Ð¹ на конкÑеÑний ÑÑенаÑÑй викоÑиÑÑаннÑ. ÐибÑÑ Ð¼Ñж ними визнаÑаÑÑÑÑÑ Ð°ÑÑ ÑÑекÑÑÑними ÑÑÑеннÑми пÑоÑкÑÑ Ñа вже наÑвними залежноÑÑÑми.
resource() ÑвлÑÑ ÑÐ¾Ð±Ð¾Ñ ÑÑндаменÑалÑний ваÑÑÐ°Ð½Ñ Ð½Ð° Ð±Ð°Ð·Ñ Promise. ФÑнкÑÑÑ params визнаÑÐ°Ñ ÑеакÑÐ¸Ð²Ð½Ñ Ð·Ð°Ð»ÐµÐ¶Ð½Ð¾ÑÑÑ, а ÑÑнкÑÑÑ loader повеÑÑÐ°Ñ Promise Ñз ÑезÑлÑÑаÑом. ÐÑи кожнÑй змÑÐ½Ñ Ð·Ð½Ð°ÑеннÑ, Ñке повеÑÑÐ°Ñ params, loader запÑÑкаÑÑÑÑÑ Ð¿Ð¾Ð²ÑоÑно, а попеÑеднÑй Ð·Ð°Ð¿Ð¸Ñ Ð°Ð²ÑомаÑиÑно ÑкаÑовÑÑÑÑÑÑ ÑеÑез AbortSignal. Цей ваÑÑÐ°Ð½Ñ Ð´Ð¾ÑÑлÑно заÑÑоÑовÑваÑи Ð´Ð»Ñ Ð¿ÑÑмиÑ
викликÑв fetch() або ÑнÑегÑаÑÑй Ñз Promise-оÑÑÑнÑованими бÑблÑоÑеками.
rxResource() пÑизнаÑений Ð´Ð»Ñ ÐºÐ¾Ð´Ð¾Ð²Ð¸Ñ
баз, де акÑивно викоÑиÑÑовÑÑÑÑÑÑ RxJS. ФÑнкÑÑÑ stream (Ñ Ð²ÐµÑÑÑÑ 19 називалаÑÑ loader) повеÑÑÐ°Ñ Observable, а ÑÑеймвоÑк внÑÑÑÑÑнÑо кеÑÑÑ Ð¿ÑдпиÑÐºÐ¾Ñ Ñа вÑдпиÑкоÑ. ÐÑÐ´Ð¿Ð°Ð´Ð°Ñ Ð½ÐµÐ¾Ð±Ñ
ÑднÑÑÑÑ Ñ ÐºÐ¾Ð½ÑÑÑÑкÑÑÑÑ
на кÑÑÐ°Ð»Ñ takeUntil(this.destroy$) або ÑÑÑÐ½Ð¾Ð¼Ñ Subject. Це ÑÑÑÐµÐ½Ð½Ñ Ð¾Ñобливо випÑавдане, коли логÑка заванÑÐ°Ð¶ÐµÐ½Ð½Ñ Ð¿Ð¾ÑÑебÑÑ RxJS-опеÑаÑоÑÑв: debounceTime, switchMap, retry ÑоÑо.
httpResource() Ñ Ð²Ð¸ÑокоÑÑÐ²Ð½ÐµÐ²Ð¾Ñ ÑпеÑÑалÑзаÑÑÑÑ Ð¿Ð¾Ð²ÐµÑÑ
HttpClient. ÐоÑÑаÑнÑо пеÑедаÑи URL або об'ÑÐºÑ ÐºÐ¾Ð½ÑÑгÑÑаÑÑÑ Ð·Ð°Ð¿Ð¸ÑÑ Ñк ÑеакÑÐ¸Ð²Ð½Ñ ÑÑнкÑÑÑ, Ñ ÑÑеймвоÑк ÑамоÑÑÑйно побÑдÑÑ HTTP-виклик Ñз ÑÑаÑ
ÑваннÑм ÑнÑеÑÑепÑоÑÑв Ñа заголовкÑв. Ðа вÑдмÑÐ½Ñ Ð²Ñд resource(), ÑÑÑ Ð½Ðµ поÑÑÑбна Ñвна ÑÑнкÑÑÑ loader. Саме Ñей ваÑÑÐ°Ð½Ñ Ñекомендовано Ð´Ð»Ñ Ð¿ÐµÑÐµÐ²Ð°Ð¶Ð½Ð¾Ñ Ð±ÑлÑÑоÑÑÑ ÑÑандаÑÑниÑ
ÑÑенаÑÑÑв оÑÑÐ¸Ð¼Ð°Ð½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ
.
ÐобÑдова пÑоÑÑÐ»Ñ ÐºÐ¾ÑиÑÑÑваÑа за Ð´Ð¾Ð¿Ð¾Ð¼Ð¾Ð³Ð¾Ñ resource()
ÐаÑÑÑпний пÑиклад ÑлÑÑÑÑÑÑ ÑобоÑÑ resource() Ð´Ð»Ñ ÑеакÑивного заванÑÐ°Ð¶ÐµÐ½Ð½Ñ Ð¿ÑоÑÑÐ»Ñ ÐºÐ¾ÑиÑÑÑваÑа. Сигнал userId ÑлÑгÑÑ ÑеакÑÐ¸Ð²Ð½Ð¾Ñ Ð·Ð°Ð»ÐµÐ¶Ð½ÑÑÑÑ: змÑна його знаÑÐµÐ½Ð½Ñ Ð°Ð²ÑомаÑиÑно ÑнÑÑÑÑÑ Ð½Ð¾Ð²Ðµ заванÑаженнÑ.
import { Component, signal, resource } from '@angular/core';
interface User {
id: number;
name: string;
email: string;
}
@Component({
selector: 'app-user-profile',
template: `
@if (userResource.hasValue()) {
<h2>{{ userResource.value().name }}</h2>
<p>{{ userResource.value().email }}</p>
} @else if (userResource.isLoading()) {
<p>Loading profile...</p>
} @else if (userResource.error()) {
<p>Failed to load user</p>
}
`,
})
export class UserProfileComponent {
userId = signal(1);
// params produces the reactive dependency
// loader receives it and returns a Promise
userResource = resource<User, number>({
params: () => this.userId(),
loader: async ({ params: id, abortSignal }) => {
const res = await fetch(`/api/users/${id}`, { signal: abortSignal });
return res.json();
},
});
loadUser(id: number) {
this.userId.set(id); // triggers automatic refetch
}
}СÑÑÑ ÑÑого паÑеÑÐ½Ñ Ð¿Ð¾Ð»ÑÐ³Ð°Ñ Ñ ÑÑÑÐºÐ¾Ð¼Ñ ÑозмежÑÐ²Ð°Ð½Ð½Ñ ÑеакÑивниÑ
залежноÑÑей Ñа логÑки заванÑаженнÑ. ФÑнкÑÑÑ params виконÑÑÑÑÑÑ Ð²ÑеÑÐµÐ´Ð¸Ð½Ñ ÑеакÑивного конÑекÑÑÑ Angular, ÑÐ¾Ð¼Ñ ÐºÐ¾Ð¶ÐµÐ½ Ñигнал, Ñкий вона зÑиÑÑÑ, авÑомаÑиÑно ÑÑÐ°Ñ Ð²ÑдÑÑежÑÐ²Ð°Ð½Ð¾Ñ Ð·Ð°Ð»ÐµÐ¶Ð½ÑÑÑÑ. Як ÑÑлÑки userId набÑÐ²Ð°Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ знаÑеннÑ, ÑÑеймвоÑк пеÑÐµÐ´Ð°Ñ abortSignal Ð´Ð»Ñ ÑкаÑÑÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾Ð¿ÐµÑеднÑого запиÑÑ Ð¹ негайно запÑÑÐºÐ°Ñ Ð½Ð¾Ð²Ð¸Ð¹ виклик loader. РозÑÐ¾Ð±Ð½Ð¸ÐºÑ Ð½Ðµ поÑÑÑбно пиÑаÑи жодного ÐºÐ¾Ð´Ñ Ð¾ÑиÑеннÑ.
ÐÐ»Ñ Ð³Ð»Ð¸Ð±Ñого ÑозÑмÑÐ½Ð½Ñ ÑиÑÑеми ÑигналÑв, Ñо лежиÑÑ Ð² оÑÐ½Ð¾Ð²Ñ Resource API, ваÑÑо ознайомиÑиÑÑ Ð· поÑÑбником Ñодо Angular Signals.
РеакÑивне оÑÑÐ¸Ð¼Ð°Ð½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ ÑеÑез httpResource
httpResource ÑпÑоÑÑÑ Ð¿Ð°ÑеÑн Ñе бÑлÑÑе, позбавлÑÑÑи вÑд необÑ
ÑдноÑÑÑ Ð¿Ð¸ÑаÑи ÑÑнкÑÑÑ loader. ФÑеймвоÑк ÑамоÑÑÑйно ÑоÑмÑÑ HTTP-запиÑ, викоÑиÑÑовÑÑÑи HttpClient Ñазом з ÑнÑеÑÑепÑоÑами, налаÑÑованими Ñ Ð·Ð°ÑÑоÑÑнкÑ.
import { Component, signal, computed } from '@angular/core';
import { httpResource } from '@angular/common/http';
interface Product {
id: number;
name: string;
price: number;
category: string;
}
@Component({
selector: 'app-product-list',
template: `
@if (products.hasValue()) {
@for (product of products.value(); track product.id) {
<div class="product-card">
<h3>{{ product.name }}</h3>
<span>{{ product.price | currency }}</span>
</div>
}
} @else if (products.isLoading()) {
<p>Loading products...</p>
}
`,
})
export class ProductListComponent {
category = signal('electronics');
// httpResource re-fetches whenever category() changes
products = httpResource<Product[]>(() => ({
url: '/api/products',
params: { category: this.category() },
}));
filterByCategory(cat: string) {
this.category.set(cat); // pending request is cancelled, new one starts
}
}ÐÑи Ð²Ð¸ÐºÐ»Ð¸ÐºÑ filterByCategory() Ñигнал category оновлÑÑÑÑÑÑ. ФÑнкÑÑÑ ÐºÐ¾Ð½ÑÑгÑÑаÑÑÑ, пеÑедана до httpResource, зÑиÑÑÑ this.category(), ÑÐ¾Ð¼Ñ ÑÑеймвоÑк ÑÑкÑÑÑ Ð·Ð¼ÑÐ½Ñ Ð·Ð°Ð»ÐµÐ¶Ð½Ð¾ÑÑÑ, ÑкаÑовÑÑ Ð¿Ð¾ÑоÑний HTTP-Ð·Ð°Ð¿Ð¸Ñ Ñ Ð·Ð°Ð¿ÑÑÐºÐ°Ñ Ð½Ð¾Ð²Ð¸Ð¹ з акÑÑалÑними паÑамеÑÑами. Ðа поведÑÐ½ÐºÐ¾Ñ Ñе аналогÑÑно опеÑаÑоÑÑ switchMap Ñ RxJS, пÑоÑе без додаÑкового ÑинÑакÑиÑного наванÑаженнÑ.
httpResource ÑозÑоблений виклÑÑно Ð´Ð»Ñ Ð¾Ð¿ÐµÑаÑÑй ÑиÑÐ°Ð½Ð½Ñ (GET-запиÑи). ÐеÑоди POST, PUT Ñа DELETE не пÑдÑÑимÑÑÑÑÑÑ. ÐÐ»Ñ Ð¾Ð¿ÐµÑаÑÑй запиÑÑ ÑлÑд викоÑиÑÑовÑваÑи HttpClient напÑÑÐ¼Ñ Ð°Ð±Ð¾ ÑеÑвеÑÐ½Ñ Ð´ÑÑ. Ðиклик .set() або .update() на resource змÑнÑÑ Ð»Ð¸Ñе локалÑне знаÑÐµÐ½Ð½Ñ ÑÐ¸Ð³Ð½Ð°Ð»Ñ Ð±ÐµÐ· вÑдпÑÐ°Ð²Ð»ÐµÐ½Ð½Ñ Ð±ÑдÑ-Ñкого запиÑÑ Ð½Ð° ÑеÑвеÑ.
ÐалÑдаÑÑÑ ÑÑ ÐµÐ¼Ð¸ за Ð´Ð¾Ð¿Ð¾Ð¼Ð¾Ð³Ð¾Ñ Zod Ñа httpResource
Ðдна з ÑиповиÑ
пÑоблем пÑи оÑÑÐ¸Ð¼Ð°Ð½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ
на ÑÑонÑÐµÐ½Ð´Ñ â ÑозбÑжнÑÑÑÑ Ð¼Ñж ÑÑÑÑкÑÑÑоÑ, ÑÐºÑ Ð¾ÑÑкÑÑ ÐºÐ»ÑÑнÑÑÑкий код, Ñа ÑÑÑÑкÑÑÑоÑ, ÑÐºÑ ÑакÑиÑно повеÑÑÐ°Ñ ÑеÑвеÑ. Angular 20 Ñозв'ÑзÑÑ ÑÑ Ð¿ÑÐ¾Ð±Ð»ÐµÐ¼Ñ ÑеÑез ÑнÑегÑаÑÑÑ Ð¼ÐµÑ
анÑÐ·Ð¼Ñ Ð²Ð°Ð»ÑдаÑÑÑ Ð±ÐµÐ·Ð¿Ð¾ÑеÑеднÑо Ñ httpResource завдÑки опÑÑÑ parse.
ÐикоÑиÑÑÐ°Ð½Ð½Ñ Zod дозволÑÑ Ð¾Ð³Ð¾Ð»Ð¾ÑиÑи оÑÑкÑÐ²Ð°Ð½Ñ ÑÑ
ÐµÐ¼Ñ Ñа валÑдÑваÑи ÐºÐ¾Ð¶Ð½Ñ Ð²ÑдповÑÐ´Ñ Ð°Ð²ÑомаÑиÑно пеÑед Ñим, Ñк Ð´Ð°Ð½Ñ ÑÑанÑÑÑ Ð´Ð¾ÑÑÑпними Ñ ÑаблонÑ. ЯкÑо валÑдаÑÑÑ Ð·Ð°Ð·Ð½Ð°Ñ Ð½ÐµÐ²Ð´Ð°ÑÑ, resource пеÑеÑ
одиÑÑ Ñ ÑÑан error з деÑалÑним опиÑом поÑÑÑеннÑ, Ñо ÑнеможливлÑÑ ÑендеÑинг некоÑекÑниÑ
даниÑ
.
import { Component, signal } from '@angular/core';
import { httpResource } from '@angular/common/http';
import { z } from 'zod';
// Define the expected shape with Zod
const OrderSchema = z.object({
id: z.number(),
status: z.enum(['pending', 'shipped', 'delivered', 'cancelled']),
total: z.number().positive(),
items: z.array(z.object({
productId: z.number(),
quantity: z.number().int().positive(),
unitPrice: z.number().positive(),
})),
createdAt: z.string().datetime(),
});
type Order = z.infer<typeof OrderSchema>;
@Component({
selector: 'app-order',
template: `
@if (order.hasValue()) {
<h2>Order #{{ order.value().id }}</h2>
<p>Status: {{ order.value().status }}</p>
<p>Total: {{ order.value().total | currency }}</p>
} @else if (order.error()) {
<p>Invalid order data received</p>
}
`,
})
export class OrderComponent {
orderId = signal(42);
// parse validates the response before exposing it as a signal
order = httpResource<Order>(
() => `/api/orders/${this.orderId()}`,
{ parse: OrderSchema.parse }
);
}ÐÑÐ¾Ð±Ð»Ð¸Ð²Ñ ÑÑннÑÑÑÑ Ñей паÑеÑн Ð¼Ð°Ñ Ñ ÐºÐ¾ÑпоÑаÑÐ¸Ð²Ð½Ð¸Ñ ÑеÑедовиÑÐ°Ñ , де API ÑÑвоÑÑÑÑÑÑÑ Ð¾ÐºÑемими командами, а ÑÑÑÑкÑÑÑа вÑдповÑдей може змÑнÑваÑиÑÑ Ð±ÐµÐ· попеÑедженнÑ. Runtime-валÑдаÑÑÑ ÑеÑез Zod дÑÑ Ñк конÑÑÐ°ÐºÑ Ð±ÐµÐ·Ð¿ÐµÐºÐ¸ мÑж ÑÑонÑендом Ñа бекендом, забезпеÑÑÑÑи негайне виÑÐ²Ð»ÐµÐ½Ð½Ñ Ð½ÐµÑÑмÑÑноÑÑей.
rxResource Ð·Ñ stream Ñа params
У ÑÑенаÑÑÑÑ
, Ñо поÑÑебÑÑÑÑ RxJS-опеÑаÑоÑÑв â напÑиклад, поле поÑÑÐºÑ Ð· debounce â rxResource пÑопонÑÑ ÑнÑеÑÑÐµÐ¹Ñ Ð½Ð° оÑÐ½Ð¾Ð²Ñ Observable. ФÑнкÑÑÑ stream (пеÑейменована з loader в Angular 20) оÑÑимÑÑ ÑеакÑÐ¸Ð²Ð½Ñ Ð¿Ð°ÑамеÑÑи Ñа повеÑÑÐ°Ñ Observable, Ñким ÑÑеймвоÑк кеÑÑÑ ÑамоÑÑÑйно.
import { Component, signal } from '@angular/core';
import { rxResource } from '@angular/core/rxjs-interop';
import { HttpClient } from '@angular/common/http';
import { inject } from '@angular/core';
import { debounceTime, switchMap } from 'rxjs';
interface SearchResult {
id: number;
title: string;
excerpt: string;
}
@Component({
selector: 'app-search',
template: `
<input (input)="query.set($any($event.target).value)" placeholder="Search..." />
@if (results.isLoading()) {
<p>Searching...</p>
}
@if (results.hasValue()) {
@for (item of results.value(); track item.id) {
<div>{{ item.title }}</div>
}
}
`,
})
export class SearchComponent {
private http = inject(HttpClient);
query = signal('');
// params (was "request") provides the reactive input
// stream (was "loader") returns an Observable
results = rxResource<SearchResult[], string>({
params: () => this.query(),
stream: ({ params: q }) =>
this.http.get<SearchResult[]>('/api/search', {
params: { q },
}),
});
}ÐÑинÑипова вÑдмÑннÑÑÑÑ rxResource вÑд resource полÑÐ³Ð°Ñ Ñ ÑÐ¸Ð¿Ñ Ð¿Ð¾Ð²ÐµÑненнÑ: Observable замÑÑÑÑ Promise. Angular беÑе на Ñебе кеÑÑÐ²Ð°Ð½Ð½Ñ Ð¿ÑдпиÑкоÑ, авÑомаÑиÑне ÑкаÑÑÐ²Ð°Ð½Ð½Ñ Ð¿Ñи змÑÐ½Ñ Ð¿Ð°ÑамеÑÑÑв Ñа ÑинÑ
ÑонÑзаÑÑÑ Ð· Ñиклом change detection. ÐÐ»Ñ Ð¿ÑоÑкÑÑв, де вже ÑиÑоко заÑÑоÑовÑÑÑÑÑÑ RxJS Ñа HttpClient, Ñаме rxResource Ñ Ð½Ð°Ð¹Ð¾ÑганÑÑнÑÑим ÑлÑÑ
ом мÑгÑаÑÑÑ.
Готовий до співбесід з Angular?
Практикуйся з нашими інтерактивними симуляторами, flashcards та технічними тестами.
ÐÑдÑÑÐµÐ¶ÐµÐ½Ð½Ñ ÑÑаÑÑÑÑ: ÑÑÐ´ÐºÐ¾Ð²Ñ Ð»ÑÑеÑали замÑÑÑÑ enum
Ðожен екземплÑÑ resource Ð½Ð°Ð´Ð°Ñ Ñигнал status(), Ñо повеÑÑÐ°Ñ ÑÑдковий лÑÑеÑал Ñз поÑоÑним ÑÑаном заванÑаженнÑ. Цей пÑдÑ
Ñд замÑнив ÑиÑÐ»Ð¾Ð²Ñ enum з попеÑеднÑÑ
веÑÑÑй, покÑаÑивÑи ÑиÑабелÑнÑÑÑÑ ÐºÐ¾Ð´Ñ Ñа зÑÑÑнÑÑÑÑ Ð²Ð¸ÐºÐ¾ÑиÑÑÐ°Ð½Ð½Ñ Ð· конÑÑÑÑкÑÑÑÑ @switch Ñ ÑаблонаÑ
.
| Status | ÐнаÑÐµÐ½Ð½Ñ |
|---|---|
| 'idle' | params повеÑнÑв undefined â Ð·Ð°Ð¿Ð¸Ñ Ð½Ðµ надÑилаÑÑÑÑÑ |
| 'loading' | ÐеÑÑий Ð·Ð°Ð¿Ð¸Ñ Ð²Ð¸ÐºÐ¾Ð½ÑÑÑÑÑÑ |
| 'reloading' | ÐовÑоÑний Ð·Ð°Ð¿Ð¸Ñ Ð¿ÑÑÐ»Ñ Ð¿Ð¾Ð¿ÐµÑеднÑого ÑÑпÑÑного ÑезÑлÑÑаÑÑ |
| 'resolved' | ÐÐ°Ð½Ñ Ð´Ð¾ÑÑÑÐ¿Ð½Ñ ÑеÑез value() |
| 'error' | ÐÐ°Ð¿Ð¸Ñ Ð·Ð°Ð²ÐµÑÑивÑÑ Ð½ÐµÐ²Ð´Ð°ÑÐµÑ â error() мÑÑÑиÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÑ |
| 'local' | ÐнаÑÐµÐ½Ð½Ñ Ð²ÑÑановлено локалÑно ÑеÑез .set() або .update() |
РозмежÑÐ²Ð°Ð½Ð½Ñ 'loading' Ñа 'reloading' Ð´Ð°Ñ Ð·Ð¼Ð¾Ð³Ñ Ð±ÑдÑваÑи диÑеÑенÑÑÐ¹Ð¾Ð²Ð°Ð½Ñ UX-паÑеÑни: повноекÑанний ÑкелеÑон пÑи пеÑÑÐ¾Ð¼Ñ Ð·Ð°Ð²Ð°Ð½ÑÐ°Ð¶ÐµÐ½Ð½Ñ Ñа непомÑÑний ÑндикаÑÐ¾Ñ Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¿Ñи пеÑезаванÑаженнÑ, коли попеÑÐµÐ´Ð½Ñ Ð´Ð°Ð½Ñ Ð·Ð°Ð»Ð¸ÑаÑÑÑÑÑ Ð²Ð¸Ð´Ð¸Ð¼Ð¸Ð¼Ð¸.
import { Component, signal, resource } from '@angular/core';
@Component({
selector: 'app-status-demo',
template: `
<p>Status: {{ data.status() }}</p>
@switch (data.status()) {
@case ('loading') { <spinner /> }
@case ('reloading') { <subtle-spinner /> }
@case ('resolved') { <data-table [rows]="data.value()" /> }
@case ('error') { <error-banner [error]="data.error()" /> }
@case ('idle') { <p>Select a filter to load data</p> }
}
`,
})
export class StatusDemoComponent {
filter = signal<string | undefined>(undefined);
data = resource({
params: () => this.filter(),
loader: async ({ params: f, abortSignal }) => {
const res = await fetch(`/api/data?filter=${f}`, { signal: abortSignal });
return res.json();
},
});
}ÐкÑÐµÐ¼Ð¾Ñ Ñваги заÑлÑговÑÑ ÑÑан 'idle': коли ÑÑнкÑÑÑ params повеÑÑÐ°Ñ undefined, resource не ÑнÑÑÑÑÑ Ð¶Ð¾Ð´Ð½Ð¾Ð³Ð¾ запиÑÑ. Цей паÑеÑн ÑеалÑзÑÑ Ñмовне заванÑаженнÑ, де Ð´Ð°Ð½Ñ Ð·Ð°Ð¿Ð¸ÑÑÑÑÑÑÑ Ð· ÑеÑвеÑа лиÑе пÑÑÐ»Ñ ÐºÐ¾Ð½ÐºÑеÑÐ½Ð¾Ñ Ð´ÑÑ ÐºÐ¾ÑиÑÑÑваÑа â обÑÐ°Ð½Ð½Ñ ÑÑлÑÑÑа, каÑегоÑÑÑ Ñи елеменÑа ÑпиÑкÑ.
ÐеÑод value() генеÑÑÑ Ð²Ð¸ÐºÐ»ÑÑеннÑ, ÑкÑо resource пеÑебÑÐ²Ð°Ñ Ñ ÑÑÐ°Ð½Ñ 'error'. ÐÐ»Ñ Ð±ÐµÐ·Ð¿ÐµÑного доÑÑÑÐ¿Ñ Ð´Ð¾ даниÑ
ÑлÑд заÑÑоÑовÑваÑи hasValue() Ñк Ñмовний заÑ
иÑÑ Ñ ÑÐ°Ð±Ð»Ð¾Ð½Ñ Ð°Ð±Ð¾ меÑод value.asReadonly(), Ñкий повеÑне undefined за вÑдÑÑÑноÑÑÑ Ð´Ð°Ð½Ð¸Ñ
. Таке пÑоÑкÑне ÑÑÑÐµÐ½Ð½Ñ Ð·Ð¼ÑÑÑÑ ÑозÑобника Ñвно обÑоблÑÑи Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¾Ð²Ñ ÑÑани, запобÑгаÑÑи Ð²Ð¸Ð¿Ð°Ð´ÐºÐ¾Ð²Ð¾Ð¼Ñ ÑендеÑÐ¸Ð½Ð³Ñ Ð½ÐµÐ²Ð°Ð»ÑдниÑ
даниÑ
.
ÐиÑÐ°Ð½Ð½Ñ Ð´Ð»Ñ ÑпÑвбеÑÑд з Angular 20 Resource API
ÐижÑе наведено пиÑаннÑ, ÑÐºÑ Ð½Ð°Ð¹ÑаÑÑÑÑе поÑÑÑÑÑÑÑÑÑ Ð½Ð° ÑÐµÑ Ð½ÑÑÐ½Ð¸Ñ ÑпÑвбеÑÑÐ´Ð°Ñ Ð´Ð»Ñ Ð¿Ð¾Ð·Ð¸ÑÑй Angular-ÑозÑобникÑв Ñ 2026 ÑоÑÑ. ÐÑдповÑÐ´Ñ Ð¼Ð°ÑÑÑ Ð´Ð¾ÑÑаÑÐ½Ñ Ð³Ð»Ð¸Ð±Ð¸Ð½Ñ Ð´Ð»Ñ Ð´ÐµÐ¼Ð¾Ð½ÑÑÑаÑÑÑ Ð¿ÑакÑиÑного володÑÐ½Ð½Ñ Resource API.
ÐиÑÐ°Ð½Ð½Ñ 1: Яка ÑÑзниÑÑ Ð¼Ñж resource(), rxResource() Ñа httpResource() в Angular 20?
resource() Ñ Ð±Ð°Ð·Ð¾Ð²Ð¸Ð¼ пÑимÑÑивом, Ñо пÑÐ¸Ð¹Ð¼Ð°Ñ ÑÑнкÑÑÑ loader, Ñка повеÑÑÐ°Ñ Promise. rxResource() пÑизнаÑений Ð´Ð»Ñ RxJS: ÑÑнкÑÑÑ stream повеÑÑÐ°Ñ Observable. httpResource() ÑвлÑÑ ÑÐ¾Ð±Ð¾Ñ Ð²Ð¸ÑокоÑÑÐ²Ð½ÐµÐ²Ñ Ð°Ð±ÑÑÑакÑÑÑ Ð½Ð°Ð´ HttpClient, де доÑÑаÑнÑо вказаÑи URL Ñа паÑамеÑÑи запиÑÑ. УÑÑ ÑÑи ваÑÑанÑи авÑомаÑиÑно вÑдÑÑежÑÑÑÑ ÑеакÑÐ¸Ð²Ð½Ñ Ð·Ð°Ð»ÐµÐ¶Ð½Ð¾ÑÑÑ ÑеÑез params, ÑкаÑовÑÑÑÑ Ð°ÐºÑÐ¸Ð²Ð½Ñ Ð·Ð°Ð¿Ð¸Ñи пÑи змÑÐ½Ñ Ð¿Ð°ÑамеÑÑÑв Ñа надаÑÑÑ ÑÑан ÑеÑез Ñигнали value(), status(), error() Ñа isLoading(). ÐибÑÑ Ð·Ð°Ð»ÐµÐ¶Ð¸ÑÑ Ð²Ñд конÑекÑÑÑ: httpResource Ð´Ð»Ñ ÑÑандаÑÑниÑ
ÑÑенаÑÑÑв, resource Ð´Ð»Ñ Ð½Ðµ-HTTP джеÑел, rxResource Ð´Ð»Ñ Ð»Ð¾Ð³Ñки з RxJS-опеÑаÑоÑами.
ÐиÑÐ°Ð½Ð½Ñ 2: Як Angular ÑеалÑзÑÑ Ð°Ð²ÑомаÑиÑне ÑкаÑÑÐ²Ð°Ð½Ð½Ñ Ð·Ð°Ð¿Ð¸ÑÑв Ñ Resource API?
ÐÑи змÑÐ½Ñ Ð·Ð½Ð°ÑеннÑ, Ñо повеÑÑаÑÑÑÑÑ ÑÑнкÑÑÑÑ params(), ÑÑеймвоÑк авÑомаÑиÑно ÑкаÑовÑÑ Ð¿Ð¾ÑоÑний запиÑ. У Ð²Ð¸Ð¿Ð°Ð´ÐºÑ resource() Ñе вÑдбÑваÑÑÑÑÑ ÑеÑез AbortSignal, пеÑеданий Ñ loader, Ñкий пÑипинÑÑ Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ fetch(). ÐÐ»Ñ rxResource() ÑÑеймвоÑк здÑйÑнÑÑ Ð²ÑдпиÑÐºÑ Ð²Ñд поÑоÑного Observable пеÑед ÑÑвоÑеннÑм нового â поведÑнка, аналогÑÑна switchMap. ÐÐ»Ñ httpResource() ÑкаÑÑÐ²Ð°Ð½Ð½Ñ ÐºÐµÑÑÑÑÑÑÑ Ð²Ð½ÑÑÑÑÑнÑми меÑ
анÑзмами HttpClient. Це запобÑÐ³Ð°Ñ Ð¿ÐµÑегоновим Ñмовам (race conditions), коли повÑлÑнÑÑа вÑдповÑÐ´Ñ Ð¼Ð¾Ð¶Ðµ виÑÑÑниÑи акÑÑалÑнÑÑÑ â ÑвиÑе, вÑдоме Ñк "stale response override".
ÐиÑÐ°Ð½Ð½Ñ 3: Що вÑдбÑваÑÑÑÑÑ, коли params() повеÑÑÐ°Ñ undefined?
Ðоли params() повеÑÑÐ°Ñ undefined, resource пеÑеÑ
одиÑÑ Ñ ÑÑан 'idle' Ñ Ð½Ðµ ÑнÑÑÑÑÑ HTTP-запиÑ. Це паÑеÑн Ñмовного заванÑаженнÑ: resource залиÑаÑÑÑÑÑ Ð½ÐµÐ°ÐºÑивним, доки не бÑдÑÑÑ Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ñ Ð½ÐµÐ¾Ð±Ñ
ÑÐ´Ð½Ñ Ð¿ÐµÑедÑмови. ÐапÑиклад, ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñ Ð´ÐµÑалей може повеÑÑаÑи undefined, поки жоден ÐµÐ»ÐµÐ¼ÐµÐ½Ñ Ð½Ðµ обÑано, Ñ ÑозпоÑинаÑи заванÑÐ°Ð¶ÐµÐ½Ð½Ñ Ð»Ð¸Ñе пÑÑÐ»Ñ Ð²Ð¸Ð±Ð¾ÑÑ. СÑан 'idle' пÑинÑипово вÑдÑÑзнÑÑÑÑÑÑ Ð²Ñд 'loading': жоден Ð·Ð°Ð¿Ð¸Ñ Ð½Ðµ виконÑÑÑÑÑÑ Ð¹ не планÑÑÑÑÑÑ, доки params() не повеÑне визнаÑене знаÑеннÑ.
ÐиÑÐ°Ð½Ð½Ñ 4: Як ÑнÑегÑÑÑÑÑÑÑ Zod-валÑдаÑÑÑ Ð· httpResource?
ÐпÑÑÑ parse в httpResource пÑÐ¸Ð¹Ð¼Ð°Ñ ÑÑнкÑÑÑ Ð²Ð°Ð»ÑдаÑÑÑ, Ñка виконÑÑÑÑÑÑ Ð½Ð°Ð´ HTTP-вÑдповÑÐ´Ð´Ñ Ð´Ð¾ Ñого, Ñк знаÑÐµÐ½Ð½Ñ ÑÑане доÑÑÑпним ÑеÑез Ñигнал value(). ÐеÑедаÑÑи OrderSchema.parse, ÐºÐ¾Ð¶Ð½Ñ Ð²ÑдповÑÐ´Ñ Ð±Ñде пеÑевÑÑено вÑдповÑдно до визнаÑÐµÐ½Ð¾Ñ Zod-ÑÑ
еми. ЯкÑо валÑдаÑÑÑ Ð½Ðµ пÑойде, resource пеÑейде Ñ ÑÑан 'error', а error() мÑÑÑиÑиме об'ÑÐºÑ ZodError Ñз пеÑелÑком поÑÑÑенÑ. Цей пÑдÑ
Ñд ÑакÑиÑно впÑоваджÑÑ runtime-конÑÑÐ°ÐºÑ Ð¼Ñж ÑÑонÑендом Ñ Ð±ÐµÐºÐµÐ½Ð´Ð¾Ð¼, Ñо Ð¼Ð°Ñ ÐºÑиÑиÑне знаÑеннÑ, коли API ÑозвиваÑÑÑÑÑ Ð½ÐµÐ·Ð°Ð»ÐµÐ¶Ð½Ð¸Ð¼Ð¸ командами й змÑни ÑÑ
еми можÑÑÑ Ð²ÑдбÑваÑиÑÑ Ð±ÐµÐ· попеÑеднÑÐ¾Ñ ÐºÐ¾Ð¾ÑдинаÑÑÑ.
ÐиÑÐ°Ð½Ð½Ñ 5: Чим ÑÑан 'loading' вÑдÑÑзнÑÑÑÑÑÑ Ð²Ñд 'reloading' Ñ ResourceStatus?
СÑан 'loading' ÑигналÑзÑÑ, Ñо виконÑÑÑÑÑÑ Ð¿ÐµÑÑий Ð·Ð°Ð¿Ð¸Ñ Ñ Ð¶Ð¾Ð´Ð½Ð¸Ñ
попеÑеднÑÑ
даниÑ
Ñ resource немаÑ. СÑан 'reloading' ознаÑаÑ, Ñо новий Ð·Ð°Ð¿Ð¸Ñ ÑозпоÑаÑо пÑÑÐ»Ñ Ð¿Ð¾Ð¿ÐµÑеднÑого ÑÑпÑÑ
Ñ: попеÑÐµÐ´Ð½Ñ Ð·Ð½Ð°ÑÐµÐ½Ð½Ñ Ð·Ð°Ð»Ð¸ÑаÑÑÑÑÑ Ð´Ð¾ÑÑÑпним ÑеÑез value() пÑд ÑÐ°Ñ Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ запиÑÑ. Ð¦Ñ Ð²ÑдмÑннÑÑÑÑ Ð´Ð¾Ð·Ð²Ð¾Ð»ÑÑ Ð±ÑдÑваÑи ÑÑÐ·Ð½Ñ UX-паÑеÑни: skeleton-loader або повноекÑанний ÑпÑÐ½Ð½ÐµÑ Ð¿Ñд ÑÐ°Ñ Ð¿ÐµÑÑого заванÑаженнÑ, а пÑи пеÑезаванÑÐ°Ð¶ÐµÐ½Ð½Ñ â диÑкÑеÑний ÑндикаÑÐ¾Ñ (пÑогÑеÑ-баÑ, Ñконка обеÑÑаннÑ) Ñз збеÑеженнÑм Ñже вÑдобÑажениÑ
даниÑ
, Ñо запобÑÐ³Ð°Ñ Ð¼ÐµÑеÑ
ÑÑÐ½Ð½Ñ Ð¿Ð¾ÑожнÑого вмÑÑÑÑ.
ÐодаÑÐºÐ¾Ð²Ñ Ð¿Ð¸ÑÐ°Ð½Ð½Ñ Ñодо ÑигналÑв Ñа SSR в Angular ÑозглÑнÑÑо Ñ ÑÑаÑÑÑ Ð¿Ñо пиÑÐ°Ð½Ð½Ñ Ð´Ð»Ñ ÑпÑвбеÑÑд з Angular 19.
ÐÑгÑаÑÑÑ Ð· пÑдпиÑок HttpClient на httpResource
Resource API каÑдиналÑно ÑкоÑоÑÑÑ Ð¾Ð±ÑÑг кодÑ, поÑÑÑбного Ð´Ð»Ñ Ð¾ÑÑÐ¸Ð¼Ð°Ð½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ
, поÑÑвнÑно з клаÑиÑним пÑдÑ
одом на оÑÐ½Ð¾Ð²Ñ ÑÑÑниÑ
пÑдпиÑок до HttpClient. ÐижÑе наведено поÑÑвнÑннÑ, Ñке наоÑно демонÑÑÑÑÑ ÑÑÑÐ½ÐµÐ½Ð½Ñ Ñаблонного ÐºÐ¾Ð´Ñ Ñа Ñвного кеÑÑÐ²Ð°Ð½Ð½Ñ Ð¶Ð¸ÑÑÑвим Ñиклом.
// BEFORE: manual subscription in ngOnInit
@Component({ /* ... */ })
export class BeforeComponent implements OnInit, OnDestroy {
private http = inject(HttpClient);
private destroy$ = new Subject<void>();
users: User[] = [];
loading = false;
error: string | null = null;
ngOnInit() {
this.loading = true;
this.http.get<User[]>('/api/users')
.pipe(takeUntil(this.destroy$))
.subscribe({
next: (data) => { this.users = data; this.loading = false; },
error: (err) => { this.error = err.message; this.loading = false; },
});
}
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
}
// AFTER: httpResource handles lifecycle automatically
@Component({ /* ... */ })
export class AfterComponent {
users = httpResource<User[]>(() => '/api/users');
// No ngOnInit, no Subject, no manual unsubscribe
// Template uses users.value(), users.isLoading(), users.error()
}ÐÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñ Ñ Ð²Ð°ÑÑанÑÑ "before" поÑÑебÑÑ ÑеалÑзаÑÑÑ OnInit Ð´Ð»Ñ ÑнÑÑÑÑÐ²Ð°Ð½Ð½Ñ Ð·Ð°Ð¿Ð¸ÑÑ, Subject Ð´Ð»Ñ ÑкаÑÑÐ²Ð°Ð½Ð½Ñ Ð¿ÑдпиÑки, окÑемиÑ
змÑнниÑ
Ð´Ð»Ñ Ð´Ð°Ð½Ð¸Ñ
, ÑÑÐ°Ð½Ñ Ð·Ð°Ð²Ð°Ð½ÑÐ°Ð¶ÐµÐ½Ð½Ñ Ñа помилки, а Ñакож OnDestroy Ð´Ð»Ñ Ð·Ð°Ð¿Ð¾Ð±ÑÐ³Ð°Ð½Ð½Ñ Ð²Ð¸Ñокам пам'ÑÑÑ. ÐаÑÑÐ°Ð½Ñ "after" зводиÑÑ ÑÑÑ ÑÑ Ð»Ð¾Ð³ÑÐºÑ Ð´Ð¾ одного деклаÑаÑивного ÑÑдка. ФÑеймвоÑк внÑÑÑÑÑнÑо беÑе на Ñебе ÑнÑÑÑÑÐ²Ð°Ð½Ð½Ñ Ð·Ð°Ð¿Ð¸ÑÑ, вÑдÑÑÐµÐ¶ÐµÐ½Ð½Ñ ÑÑанÑ, ÑкаÑÑÐ²Ð°Ð½Ð½Ñ Ñа оÑиÑÐµÐ½Ð½Ñ ÑеÑÑÑÑÑв пÑи зниÑÐµÐ½Ð½Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñа.
ÐÑобливо вÑдÑÑÑний еÑÐµÐºÑ ÑÑ Ð¼ÑгÑаÑÑÑ Ð´Ð°Ñ Ñ Ð²ÐµÐ»Ð¸ÐºÐ¸Ñ
кодовиÑ
базаÑ
, де ÑоÑÐ½Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½ÑÑв побÑÐ´Ð¾Ð²Ð°Ð½Ñ Ð·Ð° паÑеÑном ngOnInit + subscribe + takeUntil. ÐÑоÑÐµÑ Ð¿ÐµÑеÑ
Ð¾Ð´Ñ Ð¼Ð¾Ð¶Ð½Ð° виконÑваÑи поÑÑÑпово, ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñ Ð·Ð° компоненÑом, без Ð²Ð¿Ð»Ð¸Ð²Ñ Ð½Ð° ÑеÑÑÑ Ð·Ð°ÑÑоÑÑнкÑ. ÐеÑалÑнÑÑе пÑо ÑÑÑаÑегÑÑ Ð¼ÑгÑаÑÑÑ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½ÑÑв Angular опиÑано Ñ ÑÑаÑÑÑ Ð¿Ñо мÑгÑаÑÑÑ Ð½Ð° standalone components.
Починай практикувати!
Перевір свої знання з нашими симуляторами співбесід та технічними тестами.
ÐиÑновок
Resource API в Angular 20 змÑнÑÑ Ð¿ÑÐ´Ñ Ñд до оÑÑÐ¸Ð¼Ð°Ð½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ Ð² Angular-заÑÑоÑÑÐ½ÐºÐ°Ñ Ð½Ð° ÑÑндаменÑалÑÐ½Ð¾Ð¼Ñ ÑÑвнÑ. ÐлÑÑÐ¾Ð²Ñ Ð²Ð¸Ñновки:
- resource() Ñ Ð±Ð°Ð·Ð¾Ð²Ð¸Ð¼ пÑимÑÑивом Ð´Ð»Ñ Ð°ÑÐ¸Ð½Ñ Ñонного заванÑÐ°Ð¶ÐµÐ½Ð½Ñ ÑеÑез Promise з авÑомаÑиÑним ÑкаÑÑваннÑм запиÑÑв ÑеÑез AbortSignal Ñа ÑеакÑивним вÑдÑÑеженнÑм залежноÑÑей
- httpResource() Ð½Ð°Ð´Ð°Ñ Ð²Ð¸ÑокоÑÑÐ²Ð½ÐµÐ²Ñ Ð°Ð±ÑÑÑакÑÑÑ Ð½Ð°Ð´ HttpClient, Ñо ÑÑÑÐ²Ð°Ñ Ñаблонний код Ð´Ð»Ñ GET-опеÑаÑÑй Ñа наÑивно ÑнÑегÑÑÑÑÑÑÑ Ð· ÑнÑеÑÑепÑоÑами й заголовками
- rxResource() забезпеÑÑÑ ÑÑмÑÑнÑÑÑÑ Ñз RxJS Ð´Ð»Ñ Ð²Ð¸Ð¿Ð°Ð´ÐºÑв, де поÑÑÑÐ±Ð½Ñ Ð¾Ð¿ÐµÑаÑоÑи на кÑÑÐ°Ð»Ñ debounceTime Ñи retry, викоÑиÑÑовÑÑÑи Observable замÑÑÑÑ Promise
- ÐалÑдаÑÑÑ ÑеÑез Zod з опÑÑÑÑ
parseÑÑвоÑÑÑ runtime-конÑÑакÑи мÑж ÑÑонÑендом Ñа бекендом, запобÑгаÑÑи ÑендеÑÐ¸Ð½Ð³Ñ Ð½ÐµÐºÐ¾ÑекÑÐ½Ð¸Ñ Ð´Ð°Ð½Ð¸Ñ - СиÑÑема ResourceStatus Ñз ÑÑдковими лÑÑеÑалами (
'idle','loading','reloading','resolved','error','local') ÑможливлÑÑ Ð´Ð¸ÑеÑенÑÑÐ¹Ð¾Ð²Ð°Ð½Ñ UX-паÑеÑни Ð´Ð»Ñ Ð¿ÐµÑÑого заванÑÐ°Ð¶ÐµÐ½Ð½Ñ Ñа наÑÑÑÐ¿Ð½Ð¸Ñ Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ñ - ÐÑгÑаÑÑÑ Ð· паÑеÑнÑ
ngOnInit+subscribe+takeUntilвиконÑÑÑÑÑÑ Ð¿Ð¾ÑÑÑпово, ÑÑÑÑÑво зменÑÑÑÑи обÑÑг Ñаблонного ÐºÐ¾Ð´Ñ Ñа поÑенÑÑÐ¹Ð½Ñ Ð´Ð¶ÐµÑела виÑокÑв пам'ÑÑÑ
ÐÐ»Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´, ÑÐºÑ Ð³Ð¾ÑÑÑÑÑÑÑ Ð´Ð¾ ÑÐµÑ Ð½ÑÑÐ½Ð¸Ñ ÑпÑвбеÑÑд з Angular, впевнене володÑÐ½Ð½Ñ Resource API Ñа ÑÑ Ð¿Ð°ÑеÑнами викоÑиÑÑÐ°Ð½Ð½Ñ ÑÑало Ð±Ð°Ð·Ð¾Ð²Ð¾Ñ Ð²Ð¸Ð¼Ð¾Ð³Ð¾Ñ Ñ 2026 ÑоÑÑ. ÐдаÑнÑÑÑÑ Ð¿Ð¾ÑÑниÑи ÑÑзниÑÑ Ð¼Ñж ÑÑÑома ваÑÑанÑами, Ð¼ÐµÑ Ð°Ð½Ñзм авÑомаÑиÑного ÑкаÑÑÐ²Ð°Ð½Ð½Ñ Ñа ÑнÑегÑаÑÑÑ Ð· валÑдаÑÑÑÑ ÑÑ ÐµÐ¼ ÑвÑдÑиÑÑ Ð¿Ñо зÑÑле ÑозÑмÑÐ½Ð½Ñ ÑеакÑÐ¸Ð²Ð½Ð¾Ñ Ð°ÑÑ ÑÑекÑÑÑи Angular 20.
Теги
Поділитися
Пов'язані статті

Питання співбесіди Angular 19: Signals, SSR і обов'язкові концепції
Найпоширеніші питання співбесіди з Angular 19: Signals, інкрементальна гідратація, zoneless change detection і нові реактивні API з прикладами коду та очікуваними відповідями.

Angular 19 Zoneless: Продуктивність та Виявлення Змін Без Zone.js
Повний посібник з Angular zoneless change detection: видалення Zone.js, перехід на сигнали, налаштування provideZonelessChangeDetection, оптимізація SSR, міграція існуючих застосунків та підготовка до технічних співбесід з Angular.

Топ 25 Питань Співбесіди Angular: Повний Посібник до Успіху
25 найпоширеніших питань на співбесіді з Angular у 2026 році. Детальні відповіді, приклади коду та поради, щоб отримати позицію Angular-розробника.