Loading images asynchronously (Angular, Axios, jQuery, XMLHttpRequest, Html5).
Angular async pipe with Promise and Observable.
- 1. XMLHttpRequest - most ancient way to working with Images, already embedded to Browser
- 2. Require Image with Axios.
- 3. jQuery Ajax ($.ajax).
- 4. jQuery Ajax ($.get).
- 5. Lazy Loaded attribute.
- 6. Angular Async Pipe to load images asynchronously.
- 6.1. Angular project start.
- 6.2. Project template.
- 6.3. Common Angular features.
- 6.4. More details about Observable and Promise.
- 6.5. Angular Async pipe Promise template.
- 6.6. Angular Async pipe Observable template.
- 6.7. Angular Async pipe Observable template with Refresh button and Subject.
- 6.8. Angular Async pipe templates with XMLHttpRequest.
- 6.9. Angular feature - list of app-image-loader components.
- 6.10. Convert Angular component to service.
1. XMLHttpRequest - most ancient way to working with Images, already embedded to Browser
XMLHttpRequest is most important object in Javascript, you can detect - is this object present, you code working in Browser, otherwise in Node.JS or other environment (for example Windows desktop JS engine - Windows Script Host).
1: if (typeof XMLHttpRequest !== 'undefined') {
2: console.log('XMLHttpRequest is available. Running in a browser.');
3: } else {
4: console.log('XMLHttpRequest is not available. Not running in a browser.');
5: }
https://github.com/AAlex-11/ImageAsync/blob/main/Html/XHR.htm
1: <!DOCTYPE html>
2: <html lang="en">
3: <head>
4: <meta charset="UTF-8">
5: <meta name="viewport" content="width=device-width, initial-scale=1.0">
6: <title>Load Image with XMLHttpRequest</title>
7: </head>
8: <body>
9: <div id="image-container">
10: <!-- The image will be inserted here -->
11: </div>
12:
13: <script>
14: // URL of the image to load
15: const imageUrl = 'http://localhost:3000/images/Frontend.png';
16:
17: // Create a new XMLHttpRequest object
18: const xhr = new XMLHttpRequest();
19:
20: // Configure the request
21: xhr.open('GET', imageUrl, true);
22: xhr.responseType = 'blob'; // We expect the response to be a binary blob (image)
23:
24: // Define what happens when the request completes
25: xhr.onload = function () {
26: if (xhr.status === 200) {
27: // Create a Blob from the response
28: const blob = xhr.response;
29:
30: // Create an object URL for the Blob
31: const imageUrl = URL.createObjectURL(blob);
32:
33: // Create an <img> element and set its src to the object URL
34: const img = document.createElement('img');
35: img.src = imageUrl;
36: img.alt = 'Loaded Image';
37:
38: // Append the image to the container
39: const container = document.getElementById('image-container');
40: container.appendChild(img);
41:
42: // Clean up the object URL when the image is loaded
43: img.onload = function () {
44: URL.revokeObjectURL(imageUrl);
45: };
46: } else {
47: console.error('Failed to load image. Status:', xhr.status);
48: }
49: };
50:
51: // Define what happens if there's an error
52: xhr.onerror = function () {
53: console.error('An error occurred while loading the image.');
54: };
55:
56: // Send the request
57: xhr.send();
58: </script>
59: </body>
60: </html>

2. Require Image with Axios.
https://github.com/AAlex-11/ImageAsync/blob/main/Html/Axios.htm
1: <!DOCTYPE html>
2: <html lang="en">
3: <head>
4: <meta charset="UTF-8">
5: <meta name="viewport" content="width=device-width, initial-scale=1.0">
6: <title>Load Image with Axios</title>
7: <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
8: </head>
9: <body>
10: <h1>Image Loaded with Axios</h1>
11: <div id="image-container">
12: <!-- The image will be inserted here -->
13: </div>
14:
15: <script>
16: // URL of the image to load
17: const imageUrl = 'http://localhost:3000/images/Frontend.png';
18:
19: // Use Axios to load the image
20: axios.get(imageUrl, { responseType: 'blob' })
21: .then(response => {
22: // Create an object URL for the Blob
23: const imageUrl = URL.createObjectURL(response.data);
24:
25: // Create an <img> element and set its src to the object URL
26: const img = document.createElement('img');
27: img.src = imageUrl;
28: img.alt = 'Loaded Image';
29:
30: // Append the image to the container
31: const container = document.getElementById('image-container');
32: container.appendChild(img);
33:
34: // Clean up the object URL when the image is loaded
35: img.onload = function () {
36: URL.revokeObjectURL(imageUrl);
37: };
38: })
39: .catch(error => {
40: console.error('Error loading image:', error);
41: });
42: </script>
43: </body>
44: </html>

3. jQuery Ajax ($.ajax).
https://github.com/AAlex-11/ImageAsync/blob/main/Html/Ajax1.htm
1: <!DOCTYPE html>
2: <html lang="en">
3: <head>
4: <meta charset="UTF-8">
5: <meta name="viewport" content="width=device-width, initial-scale=1.0">
6: <title>Load Image with jQuery AJAX</title>
7: <!-- Include jQuery -->
8: <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
9: </head>
10: <body>
11: <div id="image-container">
12: <!-- The image will be inserted here -->
13: </div>
14:
15: <script>
16: // URL of the image to load
17: const imageUrl = 'http://localhost:3000/images/Frontend.png';
18:
19: // Use jQuery AJAX to load the image
20: $.ajax({
21: url: imageUrl,
22: method: 'GET',
23: xhrFields: {
24: responseType: 'blob' // Set the response type to Blob
25: },
26: success: function (blob) {
27: // Create an object URL for the Blob
28: const imageUrl = URL.createObjectURL(blob);
29:
30: // Create an <img> element and set its src to the object URL
31: const img = $('<img>', {
32: src: imageUrl,
33: alt: 'Loaded Image'
34: });
35:
36: // Append the image to the container
37: $('#image-container').append(img);
38:
39: // Clean up the object URL when the image is loaded
40: img.on('load', function () {
41: URL.revokeObjectURL(imageUrl);
42: });
43: },
44: error: function (xhr, status, error) {
45: console.error('Error loading image:', error);
46: }
47: });
48: </script>
49: </body>
50: </html>

4. jQuery Ajax ($.get).
https://github.com/AAlex-11/ImageAsync/blob/main/Html/Ajax2.htm
1: <!DOCTYPE html>
2: <html lang="en">
3: <head>
4: <meta charset="UTF-8">
5: <meta name="viewport" content="width=device-width, initial-scale=1.0">
6: <title>Load Image with jQuery $.get()</title>
7: <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
8: </head>
9: <body>
10: <div id="image-container">
11: <!-- The image will be inserted here -->
12: </div>
13:
14: <script>
15: // Configure jQuery to handle binary data for all $.get requests
16: $.ajaxSetup({
17: xhrFields: {
18: responseType: 'blob' // Set the response type to Blob
19: }
20: });
21:
22: // URL of the image to load
23: const imageUrl = 'http://localhost:3000/images/Frontend.png';
24:
25: // Use jQuery $.get() to load the image
26: $.get(imageUrl, function (blob) {
27: // Create an object URL for the Blob
28: const imageUrl = URL.createObjectURL(blob);
29:
30: // Create an <img> element and set its src to the object URL
31: const img = $('<img>', {
32: src: imageUrl,
33: alt: 'Loaded Image'
34: });
35:
36: // Append the image to the container
37: $('#image-container').append(img);
38:
39: // Clean up the object URL when the image is loaded
40: img.on('load', function () {
41: URL.revokeObjectURL(imageUrl);
42: });
43: }).fail(function (xhr, status, error) {
44: console.error('Error loading image:', error);
45: });
46: </script>
47: </body>
48: </html>

5. Lazy Loaded attribute
https://github.com/AAlex-11/ImageAsync/blob/main/Html/Lazy1.htm
1: <!doctype html>
2: <html lang="en">
3: <head>
4: <meta charset="UTF-8">
5: <meta name="viewport" content="width=device-width, initial-scale=1">
6: <title>Document</title>
7: </head>
8:
9: <body>
10: <img src="http://localhost:3000/images/Frontend.png" alt="Lazy Loaded Image" loading="lazy">
11: <script>
12: const img = document.querySelector('img');
13: img.onload = function () {
14: console.log('Image loaded');
15: };
16: img.onerror = function () {
17: console.error('Image failed to load');
18: };
19: </script>
20: </body>
21: </html>
Or
https://github.com/AAlex-11/ImageAsync/blob/main/Html/Lazy2.htm
1: <!DOCTYPE html>
2: <html lang="en">
3: <head>
4: <meta charset="UTF-8">
5: <meta name="viewport" content="width=device-width, initial-scale=1">
6: <title>Document</title>
7: <script>
8: // Wait for the entire page to load
9: window.onload = function () {
10: // Select the <img> element from the DOM
11: const img = document.querySelector('img');
12:
13: // Add event listeners for load and error
14: img.onload = function () {
15: console.log('Image loaded');
16: };
17: img.onerror = function () {
18: console.error('Image failed to load');
19: };
20: };
21: </script>
22: </head>
23: <body>
24: <img src="http://localhost:3000/images/Frontend.png" alt="Lazy Loaded Image" loading="lazy">
25: </body>


6. Angular Async Pipe to load images asynchronously.
6.1. Angular project start.
# npm install -g @angular/cli # ng new image-loader-app # cd image-loader-app # ng update @angular/core@19 @angular/cli@19 # npm install @angular/common@latest rxjs@latest --save # ng generate component image-loader
6.2. Project template.

In all next Angular projects I will use Angular template with lazy loading with small deviation:
1: <div *ngIf="imageUrl$ | async as imageUrl; else loading">
2: <img [src]="imageUrl" alt="Loaded Image">
3: <p>Image loaded successfully!</p>
4: </div>
5: <ng-template #loading>
6: <div class="spinner"></div>
7: </ng-template>
8: <div *ngIf="errorMessage">
9: <p style="color: red;">{{ errorMessage }}</p>
10: </div>
11: <button (click)="loadImage()">Refresh Image</button>
I will use this image server for next project templates https://github.com/AAlex-11/ImageAsync/tree/main/ImageServer
6.3. Common Angular features.
Firstly let's remember Angular syntax and features:
- Angular syntax:
- Angular Async pipe "|" - a built-in pipe that's used to automatically subscribe to an Observable and automatic updates when new data arrives
- (click) - Round brackets denote event binding (e.g., (click)="loadImage()").
- [src] - Square brackets denote property binding.
- {{ }} - Curly brackets denote interpolation (e.g., {{ errorMessage }}).
- ng-template, *ngIf, # - other basic Angular features
- Standalone Components:
- Don't need NgModule.ts bundle
- Imports need in component declarations, something like this (e.g., setTimeout, Promise, XMLHttpRequest) to trigger change detection
- What is Zone.js:
- Wrapper around asynchronous operations
- Sometimes automatic detect changing don't working we need applying changing on View manually with Zone.js
- provideZoneChangeDetection({ eventCoalescing: true }) - provide detection of multiple events into a single change detection cycle
- Angular config provide various tuning, for example
- extract-i18n Extracts internationalization (i18n) messages from the application for translation
- environment.ts
- Provide application level parameters
6.4. More details about Observable and Promise.
Angular can worki with Observable from RxJS or with JS Promise.:
- Promise - Represents a single value that will be available in the future. Observable - Represents a stream of values over time. Observable as a stream of Promises.
- The $ suffix is a naming convention for Observable variables. After unwrapping the Observable with async, the emitted value is assigned to imageUrl. imageUrl is a plain string.
JS Promise:
- Single Value. A Promise represents a single asynchronous value that will be resolved or rejected in the future.
- Eager Execution. A Promise starts executing as soon as it is created.
- Non-Cancellable. Once a Promise is created, it cannot be canceled.
- Then. and Catch Access to feature Promise value make with .then(), .catch() get exception.
1: const promise = new Promise((resolve, reject) => {
2: setTimeout(() => resolve('Data loaded!'), 1000);
3: });
4:
5: promise.then(result => console.log(result)); // Output: "Data loaded!"
RxJS Observable (More about RxJS):
- Stream of Values. An Observable represents a stream of values over time. It can emit zero, one, or multiple values.
- Lazy Execution. An Observable does not start executing until it is subscribed to.
- Cancellable. You can cancel an Observable subscription using the unsubscribe() method
- And more details about Observable, Various RxJS methods and operators applied to Observable:
- map - Transforms the emitted value (e.g., converting a Blob to a URL).
- tap - Used for side effects (e.g., logging, updating variables)
- Subject - special type of Observable that can both emit values and be subscribed to
- switchMap - operator is used to map each emission of reload$ to a new HTTP request. This ensures that only the latest request is active, preventing multiple overlapping requests.
- of - Converts the arguments to an observable sequence
1: import { Observable } from 'rxjs';
2:
3: const observable = new Observable(observer => {
4: setTimeout(() => observer.next('Data 1'), 1000);
5: setTimeout(() => observer.next('Data 2'), 2000);
6: setTimeout(() => observer.complete(), 3000);
7: });
8:
9: const subscription = observable.subscribe({
10: next: value => console.log(value), // Output: "Data 1", "Data 2"
11: complete: () => console.log('Completed!'), // Output: "Completed!"
12: });
13:
14: // Unsubscribe after 2.5 seconds
15: setTimeout(() => subscription.unsubscribe(), 2500);
6.5. Angular Async pipe Promise template.
https://github.com/AAlex-11/ImageAsync/tree/main/AngularAsyncPipe5
1: import { Component } from '@angular/core';
2: import { HttpClient } from '@angular/common/http';
3: import { AsyncPipe, CommonModule } from '@angular/common';
4: import { environment } from '../../environment';
5: import { firstValueFrom } from 'rxjs'; // Import firstValueFrom
6:
7: @Component({
8: selector: 'app-image-loader',
9: standalone: true,
10: imports: [AsyncPipe, CommonModule],
11: templateUrl: './image-loader.component.html',
12: })
13: export class ImageLoaderComponent {
14: imageUrlPromise: Promise<string | null>; // Use a Promise
15: errorMessage: string | null = null;
16:
17: constructor(private http: HttpClient) {
18: this.imageUrlPromise = this.loadImage();
19: }
20:
21: // Method to load the image using Promises
22: async loadImage(): Promise<string | null> {
23: try {
24: // firstValueFrom is a new alternatives to toPromise()
25: const blob = await firstValueFrom(this.http.get(environment.imageUrl, { responseType: 'blob' }));
26: console.log('Received Blob:', blob); // Log the Blob
27:
28: // Ensure blob is defined before creating the URL
29: if (blob) {
30: return URL.createObjectURL(blob); // Convert Blob to URL and return
31: } else {
32: throw new Error('Blob is undefined');
33: }
34: } catch (error) {
35: console.error('Error loading image:', error);
36: this.errorMessage = 'Failed to load image. Please try again later.';
37: return null;
38: }
39: }
40: }
41:
42:
1: <div *ngIf="imageUrlPromise | async as imageUrl; else loading">
2: <img [src]="imageUrl" alt="Loaded Image">
3: <p>Image loaded successfully!</p>
4: </div>
5: <ng-template #loading>
6: <div class="spinner"></div>
7: </ng-template>
8: <div *ngIf="errorMessage">
9: <p style="color: red;">{{ errorMessage }}</p>
10: </div>
11:
6.6. Angular Async pipe Observable template.
https://github.com/AAlex-11/ImageAsync/tree/main/AngularAsyncPipe1
1: import { Component } from '@angular/core';
2: import { HttpClient } from '@angular/common/http';
3: import { AsyncPipe, CommonModule } from '@angular/common';
4: import { catchError, Observable, of, tap} from 'rxjs';
5: import { map } from 'rxjs/operators';
6: import { environment } from '../../environment'
7:
8: @Component({
9: selector: 'app-image-loader',
10: standalone: true, // Mark as standalone
11: imports: [AsyncPipe, CommonModule],
12: templateUrl: './image-loader.component.html'
13: })
14: export class ImageLoaderComponent {
15: imageUrl$: Observable<string | null>;
16: errorMessage: string | null = null;
17:
18: constructor(private http: HttpClient) {
19: this.imageUrl$ = this.http.get(environment.imageUrl, { responseType: 'blob' })
20: .pipe(
21: tap(blob => console.log('Received Blob:', blob)), // Log the Blob
22: map(blob => URL.createObjectURL(blob)), // Convert Blob to URL
23: tap(url => console.log('Generated URL:', url)), // Log the generated URL
24: catchError(error => {
25: console.error('Error loading image:', error);
26: this.errorMessage = 'Failed to load image. Please try again later.';
27: return of(null);
28: })
29: );
30: }
31: }
32:
1: <div *ngIf="imageUrl$ | async as imageUrl; else loading">
2: <img [src]="imageUrl" alt="Loaded Image">
3: <p>Image loaded successfully!</p>
4: </div>
5: <ng-template #loading>
6: <div class="spinner"></div>
7: </ng-template>
8: <div *ngIf="errorMessage">
9: <p style="color: red;">{{ errorMessage }}</p>
10: </div>
11:
6.7. Angular Async pipe Observable template with Refresh button and Subject.
https://github.com/AAlex-11/ImageAsync/tree/main/AngularAsyncPipe2
1: import { Component } from '@angular/core';
2: import { HttpClient } from '@angular/common/http';
3: import { AsyncPipe, CommonModule } from '@angular/common';
4: import { Observable, of, Subject} from 'rxjs';
5: import { catchError, map, switchMap, tap } from 'rxjs/operators';
6: import { environment } from '../../environment'
7:
8: @Component({
9: selector: 'app-image-loader',
10: standalone: true, // Mark as standalone
11: imports: [AsyncPipe, CommonModule],
12: templateUrl: './image-loader.component.html'
13: })
14: export class ImageLoaderComponent {
15: imageUrl$: Observable<string | null>;
16: errorMessage: string | null = null;
17: private reload$ = new Subject<void>();// Subject to trigger reloads
18:
19: constructor(private http: HttpClient) {
20: this.imageUrl$ = this.reload$.pipe(
21: switchMap(() => this.http.get(environment.imageUrl, { responseType: 'blob' })
22: .pipe(
23: tap(blob => console.log('Received Blob:', blob)), // Log the Blob
24: map(blob => URL.createObjectURL(blob)), // Convert Blob to URL
25: tap(url => console.log('Generated URL:', url)), // Log the generated URL
26: catchError(error => {
27: console.error('Error loading image:', error);
28: this.errorMessage = 'Failed to load image. Please try again later.';
29: return of(null);
30: })
31: ))
32: );
33: // Trigger the first load
34: this.loadImage();
35: }
36:
37: // Method to trigger a reload
38: loadImage() {
39: this.errorMessage = null; // Clear any previous error message
40: this.reload$.next(); // Emit a value to trigger the reload
41: }
42: }
43:
1: <div *ngIf="imageUrl$ | async as imageUrl; else loading">
2: <img [src]="imageUrl" alt="Loaded Image">
3: <p>Image loaded successfully!</p>
4: </div>
5: <ng-template #loading>
6: <div class="spinner"></div>
7: </ng-template>
8: <div *ngIf="errorMessage">
9: <p style="color: red;">{{ errorMessage }}</p>
10: </div>
11: <button (click)="loadImage()">Refresh Image</button>
12:
6.8. Angular Async pipe templates with XMLHttpRequest
https://github.com/AAlex-11/ImageAsync/tree/main/AngularAsyncPipe3
1: import { Component } from '@angular/core';
2: import { AsyncPipe, CommonModule } from '@angular/common';
3: import { Observable, Subject, of } from 'rxjs';
4: import { catchError, map, switchMap, tap } from 'rxjs/operators';
5: import { environment } from '../../environment'
6:
7: @Component({
8: selector: 'app-image-loader',
9: standalone: true,
10: imports: [AsyncPipe, CommonModule],
11: templateUrl: './image-loader.component.html',
12: })
13: export class ImageLoaderComponent {
14: imageUrl$: Observable<string | null>;
15: errorMessage: string | null = null;
16: private reload$ = new Subject<void>(); // Subject to trigger reloads
17:
18: constructor() {
19: this.imageUrl$ = this.reload$.pipe(
20: switchMap(() => this.loadImageWithXHR()), // Use XMLHttpRequest to load the image
21: catchError(error => {
22: console.error('Error loading image:', error);
23: this.errorMessage = 'Failed to load image. Please try again later.';
24: return of(null); // Return null in case of an error
25: })
26: );
27: // Trigger the first load
28: this.loadImage();
29: }
30:
31: // Method to trigger a reload
32: loadImage() {
33: this.errorMessage = null; // Clear any previous error message
34: this.reload$.next(); // Emit a value to trigger the reload
35: }
36:
37: // Method to load an image using XMLHttpRequest
38: private loadImageWithXHR(): Observable<string> {
39: return new Observable(observer => {
40: const xhr = new XMLHttpRequest();
41: xhr.open('GET', environment.imageUrl, true);
42: xhr.responseType = 'blob'; // Set the response type to blob
43: xhr.onload = () => {
44: if (xhr.status === 200) {
45: const blob = xhr.response;
46: const imageUrl = URL.createObjectURL(blob); // Convert Blob to URL
47: observer.next(imageUrl); // Emit the image URL
48: observer.complete(); // Complete the observable
49: } else {
50: observer.error(new Error(`Failed to load image. Status: ${xhr.status}`));
51: }
52: };
53: xhr.onerror = () => {
54: observer.error(new Error('Network error while loading image.'));
55: };
56: xhr.send(); // Send the request
57: });
58: }
59: }
60:
1: <div *ngIf="imageUrl$ | async as imageUrl; else loading">
2: <img [src]="imageUrl" alt="Loaded Image">
3: <p>Image loaded successfully!</p>
4: </div>
5: <ng-template #loading>
6: <div class="spinner"></div>
7: </ng-template>
8: <div *ngIf="errorMessage">
9: <p style="color: red;">{{ errorMessage }}</p>
10: </div>
11: <button (click)="loadImage()">Refresh Image</button>
12:
6.9. Angular feature - list of app-image-loader components
https://github.com/AAlex-11/ImageAsync/tree/main/AngularAsyncPipe4
1: import { Component } from '@angular/core';
2: import { ImageLoaderComponent } from '../image-loader/image-loader.component';
3: import { CommonModule } from '@angular/common';
4:
5: @Component({
6: selector: 'app-image-list',
7: standalone: true,
8: imports: [CommonModule,ImageLoaderComponent],
9: templateUrl: './image-list.component.html',
10: styleUrls: ['./image-list.component.css'],
11: })
12: export class ImageListComponent {
13: // Define an array of image URLs
14: imageUrls: string[] = [
15: 'http://localhost:3000/images/image1.png',
16: 'http://localhost:3000/images/image2.png',
17: 'http://localhost:3000/images/image3.png',
18: 'http://localhost:3000/images/image4.png',
19: 'http://localhost:3000/images/image5.png',
20: 'http://localhost:3000/images/image6.png',
21: 'http://localhost:3000/images/image7.png',
22: 'http://localhost:3000/images/image8.png',
23: 'http://localhost:3000/images/image9.png',
24: 'http://localhost:3000/images/image10.png',
25: ];
26: }
27:
1: <div class="image-list">
2: <app-image-loader *ngFor="let url of imageUrls" [imageUrl]="url"></app-image-loader>
3: </div>

6.10. Convert Angular component to service.
# ng generate service services/image-loader
https://github.com/AAlex-11/ImageAsync/tree/main/AngularAsyncPipe6
1: // src/app/services/image-loader.service.ts
2: import { Injectable } from '@angular/core';
3: import { HttpClient } from '@angular/common/http';
4: import { Observable, of } from 'rxjs';
5: import { catchError, map, tap } from 'rxjs/operators';
6: import { environment } from '../../environment';
7:
8: @Injectable({
9: providedIn: 'root', // Make the service available application-wide
10: })
11: export class ImageLoaderService {
12: constructor(private http: HttpClient) {}
13:
14: // Method to load an image and return an Observable
15: loadImage(imageUrl: string): Observable<string | null> {
16: return this.http.get(imageUrl, { responseType: 'blob' }).pipe(
17: tap(blob => console.log('Received Blob:', blob)), // Log the Blob
18: map(blob => URL.createObjectURL(blob)), // Convert Blob to URL
19: tap(url => console.log('Generated URL:', url)), // Log the generated URL
20: catchError(error => {
21: console.error('Error loading image:', error);
22: return of(null);
23: })
24: );
25: }
26: }
27:
1: import {Component, Input, OnChanges, OnInit, SimpleChanges} from '@angular/core';
2: import { AsyncPipe, CommonModule } from '@angular/common';
3: import { Observable } from 'rxjs';
4: import { ImageLoaderService } from '../services/image-loader.service';
5:
6: @Component({
7: selector: 'app-image-loader',
8: standalone: true,
9: imports: [AsyncPipe, CommonModule],
10: templateUrl: './image-loader.component.html',
11: })
12: export class ImageLoaderComponent implements OnInit {
13: @Input() imageUrl: string = ''; // Accept an input for the image URL
14: imageUrl$: Observable<string | null> | null = null;
15: errorMessage: string | null = null;
16:
17: constructor(private imageLoaderService: ImageLoaderService) {}
18:
19: ngOnInit() {
20: this.imageUrl$ = this.imageLoaderService.loadImage(this.imageUrl);
21: }
22: }
23:

Browser context:
- (2025) Loading images asynchronously (Angular, Axios, jQuery, XMLHttpRequest, Html5). Angular async pipe with Promise and Observable. #Browser #FrontLearning #Angular
- (2025) Push Notification to Browser with WebPush, SSE, WebSocket (JS, React, Vue, Angular) #Browser #FrontLearning
- (2025) Basic workflow to working with Images (CSP, CORS), (Temporary URL as blob, Encoding image as data:image), (Fetch, Browser FileReader, Node-Fetch), (ArrayBuffer, TypedArray, DataView, HexConversion), DataStream (Concatenate Chunks, Convert data inside stream), (Image server, Image Proxy server). #Browser #FrontLearning #ES6
- (2025) Advanced Image processing (RxJs conveyor, Drag-And-Drop, Canvas WebGL/Three, OCR, EXIF, Steganography, and other - Watermark, Histogram, etc). #Browser #FrontLearning
- (2024) My workable Selenium project templates with .NET and Node.js #Browser
- (2023) List of my small freelance project 2023 #Browser #WinDesktop #NetCoreBackend #AspClassic #Css #PaymentGateway #EfCodeFirst #Voip
- (2023) Notes about browser protocol binding. #Browser
- (2023) Best animation with MIT license #Browser
- (2022) Key future of RPAT backend project #Excel #Cloud #Browser #EfCodeFirst #TimeSchedule #NetCoreBackend #Angular
- (2022) Remote debugging Angular project with VS Code (Firefox) #Browser #Angular
- (2021) Browsers future #Browser
- (2019) Multi Languages Spell Checker for webmaster. Part 4. TheArtOfDev.HtmlRenderer. #WinDesktop #Browser
- (2019) 3.5. My typical VB.NET desktop application. HtmlPanel - browser for desktop application. #WinDesktop #Browser
- (2018) CefSharp.Winforms.ChromiumWebBrowser minimal example on VB.NET (with cookies collector and script executor). #Browser #WinDesktop
- (2018) DownloadHandler for CefSharp.Winforms.ChromiumWebBrowser. #Browser #WinDesktop
- (2018) SetProxy for CefSharp.Winforms.ChromiumWebBrowser. #Browser #WinDesktop
- (2018) Parse HTML by HtmlAgilityPack (Xpath selector) and CsQuery (jQuery selector). #Browser #NetCommon
- (2018) How to Read URLs from Firefox tabs by UI Automation. #Browser
- (2018) Small .Net Wrapper Around Firefox #Browser #WinDesktop
- (2017) How to parse JSON by Newtonsoft.Json (on example of FireFox Tab Session Manager and decrypted JwtSecurityToken) #WinDesktop #Browser
- (2016) TreeView FileSelector by ReactiveNET and TheArtOfDev.HtmlRenderer (SpellChecker project). #Browser #WinDesktop #Yield #Task
- (2012) Парсинг AJAX-сайтов в среде AIR (путем выполнения jQuery-запросов из ActionScript) #Browser #Flex
- (2011) AIR приложения для платформ Android, Macintosh и Linux. #Browser #Flex
- (2007) Мой выбор - Firefox #Browser
- (2006) Программирование в среде браузера #Browser #ComObject
Angular context:
- (2025) Loading images asynchronously (Angular, Axios, jQuery, XMLHttpRequest, Html5). Angular async pipe with Promise and Observable. #Browser #FrontLearning #Angular
- (2024) Example of my Async Angular code (async chain with Fetch site icon plus async save to storage) with ActivityIndicator on frontend #Angular #Nativescript
- (2024) NativeScript and Angular form #Angular #JavascriptProjects #Nativescript
- (2024) MyVault Android phone application #Android #Angular #JavascriptProjects
- (2024) My workable project template for Angular Electron #Angular #Electron
- (2024) Node PostProcessor step for Angular and Electron. #Angular #Electron #NodeBackend
- (2023) 5 way to create modal windows with Angular (Angular material, UIKit with toggle tag, UIKit with custom function, jQuery UI modal, Bootstrap modal). #Angular #JavascriptProjects
- (2023) [Angular mosaic 1] My fast style, Intercept routing events (router-outlet onActivate event, @Input, extends base page). #Angular #JavascriptProjects
- (2023) [Angular mosaic 2] Simplest shared service (@Injectable, Subject, Injectable, LocalStorage, Store), UIkit Modal Futures (uk-modal tag, Modal from routed page and from Menu, Modal Toggle, Modal Show, Bind by On, MouseOver Modal, Modal Alert, Modal Prompt, Close button). #Angular
- (2023) [Angular mosaic 3] Standard Interceptor and JWT injector, Login page, Auth service, and Base form with FormGroup. #NetCoreBackend #Angular
- (2023) [Angular mosaic 4] Fill select/options (FormsModule, ngModel, ngModelChange, ngValue, http.get Json from Assets, LocalStorage), Angular connection service (Enable/Disable Heartbeat, Heartbeat URL, Heartbeat Interval/RetryInterval). #Angular
- (2023) [Angular mosaic 5] Net Core SignalR Client (ReactiveX/rxjs, Configure Angular injector, Abstract class, Inject SignalR service, Configure SignalR hub - forbid Negotiation, setUp Transport, URL, LogLevel, Anon or AU socket connection), Configure server Hub (MapHub endpoint, WithOrigins on CORS-policy, LogLevel, JWT AU) #NetCoreBackend #Angular
- (2023) Notes about most interesting project in my life. #Crypto #Blazor #Angular #Kvm #Linux #Ssl #NetCoreBackend #Servers #VmWare #Docker
- (2023) Server Angular (NestJs) learning. #Angular #FrontLearning
- (2022) Key future of RPAT backend project #Excel #Cloud #Browser #EfCodeFirst #TimeSchedule #NetCoreBackend #Angular
- (2022) Scaffolding Angular Client From Swagger.json #Angular #NetCoreBackend
- (2022) Setup Angular proxy #Angular
- (2022) Remote debugging Angular project with VS Code (Firefox) #Browser #Angular
- (2022) Processing Backend result in Angular frontend as typed data #Angular #NetCoreBackend
- (2022) Up and running Angular application on Android mobile phone with NativeScript. #Angular #Nativescript #Android
FrontLearning context:
- (2025) Loading images asynchronously (Angular, Axios, jQuery, XMLHttpRequest, Html5). Angular async pipe with Promise and Observable. #Browser #FrontLearning #Angular
- (2025) Push Notification to Browser with WebPush, SSE, WebSocket (JS, React, Vue, Angular) #Browser #FrontLearning
- (2025) Basic workflow to working with Images (CSP, CORS), (Temporary URL as blob, Encoding image as data:image), (Fetch, Browser FileReader, Node-Fetch), (ArrayBuffer, TypedArray, DataView, HexConversion), DataStream (Concatenate Chunks, Convert data inside stream), (Image server, Image Proxy server). #Browser #FrontLearning #ES6
- (2025) Advanced Image processing (RxJs conveyor, Drag-And-Drop, Canvas WebGL/Three, OCR, EXIF, Steganography, and other - Watermark, Histogram, etc). #Browser #FrontLearning
- (2023) Telegram Bot Learning start point #Telegram #FrontLearning
- (2023) Server Angular (NestJs) learning. #Angular #FrontLearning
- (2022) My challenge for learning new frontend technology #FrontLearning
- (2022) React Learning StartPoint #FrontLearning
- (2022) My first Progressive Web App (PWA) - useful links. #Front #FrontLearning #EfCodeFirst #AspNetMvc
- (2022) Electron learning #FrontLearning #Electron
- (2022) GraphQL learning #FrontLearning
- (2022) Vue learning #FrontLearning
- (2022) Redux Learning #FrontLearning
- (2022) Node Learning #FrontLearning
- (2022) NextJS Learning #FrontLearning
- (2022) My NativeScript learning conspectus. #Nativescript #FrontLearning
- (2022) Learning Bitcoin Telegram Bot with Firebase (Flutter & Dart) #Crypto #Telegram #FrontLearning
- (2022) My RxJs learning conspectus #FrontLearning
- (2022) Firebase Learning from Angular University #FrontLearning
- (2022) Css learning start point. #Css #FrontLearning
- (2021) Bootstrap lecture from Brad Traversy #FrontLearning #Css
- (2020) New MS tools (Vs Code) for JS development. #FrontLearning
- (2019) Useful links collection #FrontLearning #Doc
- (2019) ASP.NET Core and SPA-page on XMLHttpRequest #FrontLearning
- (2011) Знакомство с Adobe Flex 4 #Flex #FrontLearning

|