Beyond JSON: Unleashing the Power of httpResource Sub-constructors in Angular
Angular v19.2.0 introduced a powerful new feature called httpResource, designed to streamline data fetching through HTTP requests. By default, httpResource elegantly handles JSON responses, automatically deserializing them into usable JavaScript objects. However, the real world of backend APIs often extends beyond JSON. Recognizing this, the Angular team has provided us with specialized sub-constructors of httpResource that empower developers to effortlessly handle non-JSON data like plain text, binary blobs, and raw ArrayBuffers. These sub-constructors, namely httpResource.text, httpResource.blob, and httpResource.arrayBuffer, open up new possibilities for interacting with diverse backend services directly within your Angular applications. Handling non-JSON data with HttpClient previously required manual steps like setting responseType and processing raw responses, leading to verbose and error-prone code. The httpResource sub-constructors abstract this boilerplate, offering a reactive and type-safe way to consume various data formats, seamlessly integrating with Angular Signals for automatic change detection and simplified state management, similar to how httpResource handles JSON. Just like httpResource itself, these sub-constructors expect a reactive function as their first argument, which can return either a URL string or an HttpResourceRequest object, or undefined. Returning undefined from this function will postpone the HTTP request. Crucially, these sub-constructors leverage Angular Signals to monitor changes in the output of this reactive function. If the URL or any property of the HttpResourceRequest changes, the resource is updated accordingly, keeping your data fetching synchronized with your application's dynamic state. The HttpResourceRequest object allows you to configure various aspects of your HTTP request. It has the following properties: url: The URL of the request. method: The HTTP method to use for the request (e.g., 'GET', 'POST', 'PUT', 'DELETE'). It defaults to 'GET'. body: The body to be sent with the request. This is typically used for methods like 'POST' or 'PUT'. params: Query parameters that will be appended to the URL. These are often used to filter or sort data. headers: Headers that will be included with the outgoing request. You can use this to specify content types, authentication tokens, etc. context: Key-value pairs that represent the context of the request. This can be useful for passing additional information along with the request. reportProgress: A boolean value. If set to true, progress events will be enabled for the request and delivered through the HttpResource.progress Signal, allowing you to track upload or download progress. withCredential: A boolean value indicating whether or not the withCredentials flag will be set in the outgoing request. This is used to send cookies or authorization headers in cross-origin requests. transferCache: An optional property related to Server-Side Rendering (SSR) transfer cache for the request, helping to improve initial load performance. To start leveraging these exciting new features, ensure your Angular project is updated to the latest v19 release. As of this writing, the latest version is 19.2.5. You can update your project by running the following Angular CLI command: ng update @angular/core @angular/cli Let's dive into some practical examples of how to use these sub-constructors. Handling Plain Text with httpResource.text The httpResource.text sub-constructor is your go-to solution when your backend endpoint returns plain text data. It makes a reactive HTTP request and returns an HttpResourceRef, providing a Signal that holds the text content. const TEXT_URL = 'https://gist.githubusercontent.com/railsstudent/929466a301d70d65db78fc42961c8e6c/raw/956c44e5525f8fe7840f10d626820368d29fd6c3/response.txt'; @Component({ selector: 'app-resource-text', templateUrl: './httpresource-text.component.html', changeDetection: ChangeDetectionStrategy.OnPush, }) export class HttpResourceTextComponent { textUrl = TEXT_URL; textSignal = signal(''); textResource = httpResource.text( () => this.textSignal() ? this.textSignal() : undefined, { defaultValue: '' }); textError = computed(() => this.textResource.error() ? this.textResource.error() as Error : undefined ); } The HttpResourceTextComponent creates a textResource that retrieves a string from TEXT_URL and the defaultValue in the HttpResourceOptions is set to an empty string. The textError computed signal shows the error when the httpResource throws an error. Load text {{ `Url: ${textSignal()}` }} @if (textResource.isLoading()) { Loading... } @else if (textError()) { Error: {{ textError()?.message }} } @else if (textResource.hasValue()) { Text: {{ textResource.value() }} } The template displays "Loading..." when the httpResource's status is loading. When it causes an error, the temp

Angular v19.2.0 introduced a powerful new feature called httpResource
, designed to streamline data fetching through HTTP requests. By default, httpResource elegantly handles JSON responses, automatically deserializing them into usable JavaScript objects. However, the real world of backend APIs often extends beyond JSON. Recognizing this, the Angular team has provided us with specialized sub-constructors of httpResource that empower developers to effortlessly handle non-JSON data like plain text, binary blobs, and raw ArrayBuffers. These sub-constructors, namely httpResource.text
, httpResource.blob
, and httpResource.arrayBuffer
, open up new possibilities for interacting with diverse backend services directly within your Angular applications.
Handling non-JSON data with HttpClient
previously required manual steps like setting responseType
and processing raw responses, leading to verbose and error-prone code. The httpResource sub-constructors abstract this boilerplate, offering a reactive and type-safe way to consume various data formats, seamlessly integrating with Angular Signals for automatic change detection and simplified state management, similar to how httpResource handles JSON.
Just like httpResource itself, these sub-constructors expect a reactive function as their first argument, which can return either a URL string or an HttpResourceRequest
object, or undefined. Returning undefined from this function will postpone the HTTP request. Crucially, these sub-constructors leverage Angular Signals to monitor changes in the output of this reactive function. If the URL or any property of the HttpResourceRequest changes, the resource is updated accordingly, keeping your data fetching synchronized with your application's dynamic state.
The HttpResourceRequest
object allows you to configure various aspects of your HTTP request. It has the following properties:
- url: The URL of the request.
- method: The HTTP method to use for the request (e.g., 'GET', 'POST', 'PUT', 'DELETE'). It defaults to 'GET'.
- body: The body to be sent with the request. This is typically used for methods like 'POST' or 'PUT'.
- params: Query parameters that will be appended to the URL. These are often used to filter or sort data.
- headers: Headers that will be included with the outgoing request. You can use this to specify content types, authentication tokens, etc.
- context: Key-value pairs that represent the context of the request. This can be useful for passing additional information along with the request.
- reportProgress: A boolean value. If set to true, progress events will be enabled for the request and delivered through the HttpResource.progress Signal, allowing you to track upload or download progress.
- withCredential: A boolean value indicating whether or not the withCredentials flag will be set in the outgoing request. This is used to send cookies or authorization headers in cross-origin requests.
- transferCache: An optional property related to Server-Side Rendering (SSR) transfer cache for the request, helping to improve initial load performance.
To start leveraging these exciting new features, ensure your Angular project is updated to the latest v19 release. As of this writing, the latest version is 19.2.5. You can update your project by running the following Angular CLI command:
ng update @angular/core @angular/cli
Let's dive into some practical examples of how to use these sub-constructors.
Handling Plain Text with httpResource.text
The httpResource.text
sub-constructor is your go-to solution when your backend endpoint returns plain text data. It makes a reactive HTTP request and returns an HttpResourceRef
, providing a Signal that holds the text content.
const TEXT_URL = 'https://gist.githubusercontent.com/railsstudent/929466a301d70d65db78fc42961c8e6c/raw/956c44e5525f8fe7840f10d626820368d29fd6c3/response.txt';
@Component({
selector: 'app-resource-text',
templateUrl: './httpresource-text.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class HttpResourceTextComponent {
textUrl = TEXT_URL;
textSignal = signal('');
textResource = httpResource.text(
() => this.textSignal() ? this.textSignal() : undefined, {
defaultValue: ''
});
textError = computed(() =>
this.textResource.error() ? this.textResource.error() as Error : undefined
);
}
The HttpResourceTextComponent
creates a textResource
that retrieves a string from TEXT_URL
and the defaultValue
in the HttpResourceOptions
is set to an empty string. The textError
computed signal shows the error when the httpResource throws an error.
{{ `Url: ${textSignal()}` }}
@if (textResource.isLoading()) {
Loading...
} @else if (textError()) {
Error: {{ textError()?.message }}
} @else if (textResource.hasValue()) {
Text: {{ textResource.value() }}
}
The template displays "Loading..." when the httpResource
's status is loading. When it causes an error, the template displays an error message. When the text is available, the template displays the fetched text value.
Handling Binary Data with httpResource.blob
When dealing with binary data like images, audio files, or PDFs, httpResource.blob is the perfect choice. It returns an HttpResourceRef
, allowing you to work directly with the binary data.
export function makeResourceRefStatus(resourceRef: HttpResourceRef<unknown | undefined>){
return {
progress: computed(() => {
if (resourceRef.progress()) {
const progress = resourceRef.progress();
return `${progress?.loaded}/${progress?.total}`
}
return '';
}),
error: computed(() =>
resourceRef.error() ? resourceRef.error() as Error : undefined
)
}
}
const PIKACHU_OGG_URL = 'https://raw.githubusercontent.com/PokeAPI/cries/main/cries/pokemon/latest/25.ogg';
@Component({
selector: 'app-resource-blob',
templateUrl: './httpresource-blob.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class HttpResourceBlobComponent {
audioUrl = PIKACHU_OGG_URL;
audioSignal = signal('');
audioResource = httpResource.blob(
() => this.audioSignal() ? {
url: this.audioSignal(),
reportProgress: true,
} : undefined
);
resourceRefStatus = makeResourceRefStatus(this.audioResource);
audioProgress = this.resourceRefStatus.progress;
audioError = this.resourceRefStatus.error;
blobURL = computed(() =>
this.audioResource.hasValue() ?
URL.createObjectURL(this.audioResource.value()) :
undefined
);
}
The first argument to httpResource.blob
is a reactive function that returns either an HttpResourceRequest
or undefined. In this case, when this.audioSignal()
has a value, it returns an HttpResourceRequest
object. This request enables progress events (reportProgress: true)
to report the total bytes and the bytes received during the download. The makeResourceRefStatus
helper function constructs the progress
and error
computed signals to be displayed in the template.
{{ `Url: ${audioSignal()}` }}
{{ `Progress: ${audioProgress()}` }}
@if (audioError()) {
Error: {{ audioError()?.message }}
} @else if (blobURL()) {
Listen to Pikachu:
}
blobURL
is a computed signal that creates a URL object from the fetched Blob using URL.createObjectURL()
. This URL object
is then assigned to the src
attribute of the element, allowing the browser to play the sound.
Handling Raw Binary Data with httpResource.arrayBuffer
For scenarios where you need to work with the raw binary data as an ArrayBuffer, httpResource.arrayBuffer
is the ideal choice. It returns an HttpResourceRef
.
const PIKACHU_IMAGE_URL = 'https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/shiny/25.png';
@Component({
selector: 'app-resource-array-buffer',
templateUrl: './httpresource-arraybuffer.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class HttpResourceArrayBufferComponent {
imageUrl = PIKACHU_IMAGE_URL;
imageSignal = signal('');
imgResource = httpResource.arrayBuffer(
() => this.imageSignal() ? {
url: this.imageSignal(),
reportProgress: true,
method: 'GET'
} : undefined
);
resourceRefStatus = makeResourceRefStatus(this.imgResource);
imgProgress = this.resourceRefStatus.progress;
imgError = this.resourceRefStatus.error;
bufferedImage = computed(() => {
return this.imgResource.hasValue() ?
URL.createObjectURL(new Blob([this.imgResource.value()])) :
undefined;
});
}
The HttpResourceArrayBufferComponent
uses the httpResource.arrayBuffer
sub-constructor to retrieve an image file. The reactive function returns an HttpResourceRequest
that specifies the URL and enables progress reporting.
{{ `Url: ${imageSignal()}` }}
{{ `Progress: ${imgProgress()}` }}
@if (imgError()) {
Error: {{ imgError()?.message }}
} @else if (bufferedImage()) {
[src]="bufferedImage()" alt="Pikachu">
}
The template allows you to load the image, displays the loading progress and any errors, and finally renders the image using the generated bufferedImage URL.
To see these components in action, you can import them into your AppComponent
to display each example:
@Component({
selector: 'app-root',
imports: [
HttpResourceBlobComponent,
HttpResourceArrayBufferComponent,
HttpResourceTextComponent
],
templateUrl: './app.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class App {
version = VERSION.full;
prs = [
'https://github.com/angular/angular/pull/59876',
];
name = 'httpResource sub-constructors';
description = 'httpResource functions to query non-JSON data';
}
{{ `${version} - ${name}` }}
{{ description }}
PR:
@for (pr of prs; track pr) {
[href]="pr" target="_blank">{{ pr }}
}
/>
/>
/>
/>
/>
/>
Benefits of Using httpResource Sub-constructors
- Utilizing these specialized httpResource sub-constructors offers several key advantages:
- Simplified Data Handling: They abstract away the manual steps of handling different responseTypes and processing raw data, leading to cleaner and more concise code.
- Reactive Integration: They seamlessly integrate with Angular Signals, providing reactive data streams and automatic change detection.
- Type Safety: The HttpResourceRef provides type safety for the expected data type (string, Blob, or ArrayBuffer), reducing the risk of runtime errors.
- Consistent API: They follow the same API structure as the base httpResource, making it easier for developers to learn and use.
- Progress Reporting: The HttpResourceRequest allows for easy configuration of progress event reporting for binary data transfers.
- Error Handling: Consistent error handling through the error() Signal.
- Deferred Execution: The ability to defer the request execution until the reactive URL function returns a value. Dynamic Updates: Automatic re-execution of the request when the reactive URL function changes.
- Fine-grained Control: The HttpResourceRequest provides granular control over the HTTP request and its behavior.
Conclusion
The introduction of httpResource.text
, httpResource.blob
, and httpResource.arrayBuffer
in Angular 19.2.0 marks a significant step forward in simplifying the consumption of non-JSON data within Angular applications. By providing a reactive and type-safe approach, along with detailed configuration options through HttpResourceRequest, these sub-constructors empower developers to interact with a wider range of backend services more efficiently and with less boilerplate. Embrace these new tools to build more robust and versatile Angular applications.
Resources
- The PR relevant to httpResource - https://github.com/angular/angular/pull/59876
- The httpResource.arrayBuffer documentation: https://angular.dev/api/common/http/httpResource#httpResource_arrayBuffer_0
- The httpResource.blob documentation: https://angular.dev/api/common/http/httpResource#httpResource_blob_0
- The httpResource.text documentation: https://angular.dev/api/common/http/httpResource#httpResource_text_0
- Stackblitz demo: https://stackblitz.com/edit/stackblitz-starters-peg6m2d6?file=src%2Fmain.ts