Avoid flickering of images by properly handling the object URL when setting the image source in an asynchronous pipe

Implementing a JWT authorized endpoint for images has made it impossible to directly link to image urls in HTML.

To work around this issue, we have created an async pipe that loads the image with proper authorization (handled by an HTTP interceptor, not shown) and sets the img.src attribute to an "object" URL.

Here is how it looks in the HTML:

<img [attr.src]="environment.apiUrl + 'users/image/' + userId | secureImage | async" alt="Avatar" />

The Pipe used is as follows:

import { Pipe, PipeTransform } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

@Pipe({
    name: 'secureImage'
})
export class SecureImagePipe implements PipeTransform {

    constructor(private http: HttpClient, private sanitizer: DomSanitizer) { }

    transform(url): Observable<SafeUrl> {
        return this.http
            .get(url, { responseType: 'blob' })
            .pipe(map(val => this.sanitizer.bypassSecurityTrustUrl(URL.createObjectURL(val))));
    }
}

In the GIF demonstration provided, when the image changes from the static plus sign to the dynamically loaded homer brain using the pipe, there is a brief flicker displaying the "image not found" text along with the alt text (Avatar).

View Flicker GIF

We are looking for suggestions on how to eliminate or reduce this flickering effect.

UPDATE: Removing the "alt" attribute removes the "broken image" icon, resulting in a smoother display.

For example, changing from this:

<img [attr.src]="environment.apiUrl + 'users/image/' + userId | secureImage | async" alt="Avatar" />

to this:

<img [attr.src]="environment.apiUrl + 'users/image/' + userId | secureImage | async" />

We will keep this question open as some users may require the alt attribute, making our solution unsuitable for them.

Answer №1

Upon clicking the button and initiating the image loading process, there exists a brief moment during which the image has not completely loaded from the server and the < img > will exhibit the alt text.

To rectify this issue, retrieve the image from the server using a component or service and delay setting the src until the image has been fully loaded.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Angular application using ngrx-store-localstorage does not retain data after a page refresh

Looking to incorporate ngrx into my authentication flow with the help of ngrx-store-localstorage for token persistence between browser sessions. After logging in, I can see the token value stored like this: {"token":{"token":"e5cb6515-149c-44df-88d1-4ff1 ...

Preserving chosen options in a dropdown menu using PHP and HTML

I'm facing an issue with my code where the selected values in a dropdown menu revert back to default every time the page refreshes. How can I ensure that the selected values remain unchanged? Unfortunately, I am unable to utilize AJAX as per the user ...

Angular data table is currently displaying an empty dataset with no information available

While attempting to display a data table in Angular JS, an issue arose where the table showed no available data despite there being 4 records present. Refer to the screenshot below for visual reference. https://i.sstatic.net/hdaW9.png This is the approac ...

Issues with Angular application navigation in live environment

While my website functions perfectly on the development server, I encounter a strange error when I publish it to production on GitHub pages. Visiting the URL (yanshuf0.github.io/portfolio) displays the page without any issues. However, if I try to access y ...

As you minimize the browser window, you may notice a white space appearing when scrolling over

Encountering an issue with my webpage where, upon minimizing the browser horizontally and causing overflow, scrolling over to view the hidden section results in a blank page. Any idea why this is happening? I have set my divs to a specific height (e.g. 9 ...

How can the table header be displayed in a Vue JS application after receiving the server response?

On my Vue.JS web page, I am making an API call using the Http GET method. Currently, the table header is displayed before receiving the API response, which doesn't look good. Can someone help me modify my code so that the table header is only displaye ...

Top Method for Connecting Numerous Dependent HTTP Requests Without the Need for Multiple Subscriptions and Iterations

I'm working on an angular project where I have an API that creates a line item and then loops through to call the API for each modification before firing the print request. Currently, I am using multiple subscribes for this process and I was wondering ...

Do not insert a MUI divider after the final item in the menu

Is there a way to remove the divider after the last category when using MUI components and adding a divider after each category? https://i.sstatic.net/Gx0Zb.png This is my code with the divider right at the bottom before the closing tag. export const ...

Displaying the product quantity counter in the shopping cart immediately after adding the item

My website has a shopping cart quantity counter that doesn't update immediately when a product is added. Instead, it requires a page reload or navigation to another page for the change to be reflected. I would like the quantity counter to show the pro ...

Display endless data within a set window size

I am looking to create a fixed-size window for displaying text from the component <Message/>. If the text is longer, I want it to be scrollable within the fixed window size. See screenshot below: Screenshot export default function AllMessages(){ ...

Creating fixtures with Playwright is a simple process that can greatly enhance

I have a requirement to set up fixtures where the first fixture is always available (acting as a base class) and the second fixture will vary in different test files (like a derived class). I've implemented the following code which seems to be working ...

Spin only the outline with CSS

I have a unique idea for my webpage - three spinning circles surrounding text, while the text itself remains stationary. My challenge is to achieve this effect using only CSS, specifically by utilizing the .spinner-border class from Bootstrap. I cannot ma ...

Tips for ensuring that your website can recall which call-to-action (CTA) has been selected for redirection

I'm attempting to create a bilingual webpage in Spanish and English. My goal is to have a main page where the user selects the language, and once chosen, the page remembers the language preference for future visits instead of prompting the choice agai ...

It appears that IE 10 is having trouble displaying modals, possibly due to a compatibility issue with jQuery 1.7.1's animate function

By visiting www.carsense.com and clicking on the login link in the top-right corner, you may notice that the curtain appears but the modal itself does not display, even though it exists: If you locate id="content1" and modify the inline opacity to 1, the ...

Tips for adding extra spacing between icon and text field using Vuetify

The code snippet below is used for the username section: <v-text-field prepend-icon="fas fa-user" height="60px" placeholder="Username" outlined ></v-text-field> Is there a way to add space between the user ...

Unable to locate the name 'JSON' in the typescript file

I have been working on an angular application where I have implemented JSON conversion functionalities such as JSON.stringify and JSON.parse. However, I encountered an error stating 'Cannot find name 'JSON''. Furthermore, there is anoth ...

Sliding with jQuery to eliminate a div element

I wanted to dive into jQuery and decided to recreate the slick animation from Jay-Z's new album commercials. In these ads, a bar slides left over his name while simultaneously disappearing. I also wanted to add a flashing effect by fading out, fading ...

Using ngModel to bind input fields with predefined default values

I have an input field and I'm trying to set default values, but when using ngModel the input fields are coming up empty. How can I set default values that the user can change? <div class="control"> <input #name="ngModel" ...

Steps to fully eliminate the recent action panel from Django's administrative user interface

Is there a way to completely remove the recent action panel from Django admin UI? I have searched extensively but all the information I find is about clearing the data in the panel from the database. What I'm looking for is a way to entirely eliminate ...

Achieve uniform display across browsers: Implement Chrome's overflow ellipsis feature on Firefox

I am seeking a CSS solution to achieve the same "overflow: hidden" and "text-overflow: ellipsis" behavior in Firefox as I get in Chrome. In Chrome, when the width of the tag is reduced, the text gets hidden and replaced with an ellipsis. However, in Firefo ...