Using Angular, a function can be called recursively directly from within the HTML

I'm struggling with loading an image because the method getUserProfileImage() is getting triggered multiple times within a loop. Is there a way to ensure the method is only called once during each iteration? I understand that this issue is related to Angular's change detection strategy, but how can I effectively address it?

I've done some research on this topic and found several solutions involving hacks to stop change detection strategy, but I prefer not to resort to such workarounds.

    <div *ngFor="let user of listOfContacts">
            <img class="rounded profile-thumbnail ptr" [src]="getUserProfileImage(user.UserName, user.UserId)" id="image-id-{{user.UserId}}" [routerLink]="['/community/userProfile', '0', user.UserId]">
    </div>

getUserProfileImage() method located in ____.ts class

    getUserProfileImage(userName: string, itemId: number){

      let loadImageSub = this.util.getUserProfileImageByUserName(userName).subscribe(contactsObj => {

      let imageUrl = this.toUrl(contactsObj["Images"][0].SrcAttr);
      console.log("contact profile image", imageUrl);
      (<HTMLInputElement>document.getElementById("image-id-" + itemId)).src = imageUrl;
      loadImageSub.unsubscribe();

    });
 }

Error: The same image is being loaded repeatedly, causing recursive function calls.

Answer №1

Avoid calling functions in templates whenever possible, as you have already pointed out yourself. It seems like you are aiming to retrieve all data before rendering the template, ensuring a well-structured data format with images stored within each object for display using ngFor.

If your contacts are being fetched from an API call, consider utilizing forkJoin and switchMap to obtain the image URL for each object. The following example demonstrates fetching all users first, followed by retrieving posts associated with each user and storing them in a posts property within the original user data. Modify this approach according to your use case. Instead of using any, strive to specify data types for clarity.

// Retrieve all users first!
this.getUsers()
  .pipe(
    switchMap((data: any) => {
      // For each user, fetch their posts and combine with original user data
      return forkJoin(
        data.map((user: any) =>
          this.getPosts(user.id).pipe(map((postData) => ({ ...user, posts: postData }))
        )
      );
    })
  )
  .subscribe(data => console.log(data));

In your scenario, apply the same logic within switchMap to use forkjoin on all contact person images, attaching them to a property in your contact object instead of posts as demonstrated in the sample code above :)

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

Is it possible to select a tab in Angular 10 Material Tabs based on a route parameter?

My webpage features a mat-tab-group, located at the URL /transactions. <mat-tab-group> <mat-tab label="Shipments"> <ng-template matTabContent> shipment content </ng-template> ...

Is there a way to merge my local store with Firestore using ngrx entity?

Currently, I'm facing a challenge while using NgRx and Firestore as I attempt to keep the local store in sync with a firestore collection. I have set up an observable that triggers when the firestore collection is updated. However, in my reducer, I am ...

angular datatable pagination issue with mdb

I've been following a tutorial at this website: Unfortunately, I keep encountering an error whenever I attempt to use pagination. Cannot read property 'setMaxVisibleItemsNumberTo' of undefined This is how my HTML code looks: <table ...

"Series of Subscriptions: Unleashing New

I have a ReplaySubject that is subscribed to by multiple components. I am curious about the order in which these subscriptions are processed. public getValue$ = new ReplaySubject<any>(1); If I send a value to getValue$ using getValue$.next(5); Assu ...

Synchronizing Headers in the Angular PDF Viewer Control by Syncfusion

We implement token-authentication on our endpoints and I am interested in using the standard approach provided by Syncfusion for viewing a PDF. My main concern is whether it's feasible to include headers with the request. Although I have posted this q ...

What are some alternatives for integrating React production build files apart from utilizing Express?

Is there a way to integrate React into my library using the HTTP module? I'm trying to figure out how to recursively send static files. Specifically, I want to include the build folder from the React production build, but I'm not sure how to go a ...

Utilizing symbols as a keyof type: A simple guide

Let's consider the following: type Bar = keyof Collection<string> In this scenario, Bar denotes the type of keys present in the Collection object, such as insert or remove: const x: Bar = 'insert'; ✅ But wait, the Collection also c ...

JavaScript library declaration files are essential for providing type definitions and enabling

I have encountered a problem with my JS library and its declaration files (*.d.ts) in my TypeScript projects. For some reason, my TS project seems to be ignoring these declaration files. To investigate this issue further, I decided to conduct a simple tes ...

The type 'MenuOptions[]' cannot be assigned to type 'empty[]'

Even after numerous attempts, I am still grappling with TypeScript problems. Currently, I am at a loss on how to resolve this particular issue, despite all the research I have conducted. The code snippet below is what I am working with, but I am struggling ...

Typescript's forEach method allows for iterating through each element in

I am currently handling graphql data that is structured like this: "userRelations": [ { "relatedUser": { "id": 4, "firstName": "Jack", "lastName": "Miller" }, "type": "FRIEND" }, { "relatedUser": ...

What steps can be taken to troubleshoot and resolve this specific TypeScript compilation error, as well as similar errors that may

I am struggling with this TypeScript code that contains comments and seems a bit messy: function getPlacesToStopExchange(): { our: { i: number; val: number; }[]; enemy: { i: number; val: number; }[]; //[party in 'our' | 'enemy' ]: ...

Clearing dropdown values when navigating back on a page in Angular 6: A step-by-step guide

Image Within the App Component, I have implemented a dropdown list. When an option is selected from the dropdown, it should navigate to another page using routing. Additionally, upon clicking the back button, it should return the user to the app compone ...

I encountered an issue with uploading an image file in Angular and am currently experiencing an error

media.components.html <div class="row justify-content-center" style="position:relative;top:105px;"> <div class="col-md-6"> <!-- form company info --> <div class="card card-outline-secondary"> <div ...

Comparing Angular's 'ng serve' and 'npm start' commands

Just a quick query regarding angular-cli. I'm curious, is it correct that when I use ng serve, I am utilizing the global installation of angular-cli but when I opt for npm start, I am using the local one? ...

Tips for customizing the event target appearance in Angular 2?

After following the steps outlined in this particular blog post (section 3, event binding), I successfully added an event listener to my component class. I can confirm that it responds when the mouse enters and exits. <p class="title" (mouseenter)="unf ...

unable to select date on mat-calendar

I'm trying to add special dates to a mat-calendar by highlighting them. Here's the code I have so far: app.component.ts: datesToHighlight = ["2019-06-22T18:30:00.000Z", "2019-06-06T18:30:00.000Z", "2019-06-24T18:30:00.000 ...

Utilize npm to compile TypeScript files as part of the npm build script execution

I am in the process of creating a build script using only npm, without relying on grunt or gulp. Most aspects are functioning well except for concatenating typescript files. While I can compile individual typescript files successfully, I am faced with th ...

The switchMap function is sending back a single item

I'm having an issue with switching the observable using the switchMap operator: return this.db.list(`UserPlaces/${this.authData.auth.auth.currentUser.uid}`, { query: { orderByChild: 'deleted', equalTo: false } }) .ma ...

Establish a reactive form upon data completion (asynchronously) in Angular version 5

I've been encountering an issue with updating form values post fetching data from an API. I attempted to utilize the *ngIf technique, but unfortunately, the form remains invisible even though it is properly set. Although I cannot provide the entire p ...

"Using Angular and TypeScript to dynamically show or hide tabs based on the selected language on a website

When switching the language on the website, I want to display or hide a specific tab. If the language is set to German, then show the tab; if any other language is selected, hide it. Here's my code: ngOnInit(): void { this.translate.onLangChange.s ...