What is the best way to incorporate a function within an ngIf statement in Angular?

There are 2 functions in my code

loadItems(): void {
this.service.query().subscribe((res: HttpResponse<Item[]>) => 
 (this.items = res.body || []));
 }
 
loadAuditByItem(item: Item) {
this.service.auditByItem(item.id!).subscribe((res: HttpResponse<ItemAudit[]>) => 
(this.auditByItem = res.body || []));
 }

I am trying to showcase data from both loadItems() and loadAuditByItem() on the same page. I have successfully displayed the name and description from loadItems(), but I also need to show the "createdBy" information from loadAuditByItem(item).

<div *ngFor="let item of items">
    <div *ngIf="loadAuditByItem(item)">
        <span>Name: {{ item.name}}</span>
        <span>Description : {{ item.description }}</span>
        <span>Created by: {{ auditByItem .createdBy}}</span>
    </div>
</div>

Answer №1

Employing a function call within the ngIf can significantly impact performance (you can verify this by adding a console.log and monitoring how many times it is invoked). Instead, consider utilizing Pipes. With that being said, here's a solution tailored to your specific scenario:

import { forkJoin, Observable, of, Subject } from "rxjs";
import { map, switchMap } from "rxjs/operators";
...

  public items$: Observable<Item[]>;

...

  loadItems(): void {
    // It's advisable to enhance your backend API to retrieve all data in a single call
    // Nested calls could result in an N+1 calls issue.

    this.items$ = this.service.query().pipe(
      map((res: HttpResponse<[]>) => res.body || []),
      switchMap((items: []) => {

        if (items.length === 0) {
          return of([]);
        }

        return forkJoin(
          items.map((item: any) =>
            this.service.auditByItem(item.id).pipe(
              map(audit => {
                item.audit = audit;
                return item;
              })
            )
          )
        );
      })
    );
  }
<div *ngFor="let item of (items$ | async)">
    <div>
        <span>Name: {{ item.name}}</span>
        <span>Description : {{ item.description }}</span>
        <span>Created by: {{ item.audit.createdBy}}</span>
    </div>
</div>

Bonus: It's not recommended to expose HttpResponse directly from the service; it's better to solely return the Item[] and encapsulate the HttpResponse internally.

Answer №2

To make it easier for *ngIf to handle the subscription, I decided to return the Observable and utilize the AsyncPipe.

public fetchAuditRecord(item: Item): Observable<any> {
    return this.service.retrieveAuditRecordByItem(item.id!);
}
<div *ngFor="let item of items">
    <div *ngIf="fetchAuditRecord(item) | async as audit">
        <span>Name: {{ item.name }}</span>
        <span>Description : {{ item.description }}</span>
        <span>Created by: {{ audit.createdBy }}</span>
    </div>
</div>

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

Exploring the use of @Query() object in Nest.js for iteration

How can we loop through an object passed to the controller using @Query() annotations? We are dealing with a varying number and names of query parameters in our GET request, so we require the entire @Query() object to iterate through and determine the exa ...

The map function in Math.min returns NaN when there is a 0 in the collection

I'm currently troubleshooting a code snippet that involves determining the minimum and maximum values within a collection. Everything was functioning well until I added 0 values to the collection, which caused the function to return NaN. The function ...

I am attempting to fetch data from an API and display it on the screen, yet I am encountering an issue where only the latest data from the API response is being rendered

HotelPage.tsx export interface Hotel { id: string; name: string; address1: string; address2: string; starRating: number; images: string[]; longDescription: string; } export interface Room { id: string; name: string; longDescription: st ...

Managing data with Angular 2: Setting and retrieving values

In my current project, I am working on developing a service that can parse data to different components based on various routes. When I call this service within the same component, everything works as expected and I get the desired results. However, when ...

Adding a visible icon to an Angular Material dropdown: A step-by-step guide

Seeking help on integrating a clear icon to the right side of a dropdown (select component) in Angular Material, only visible when an option is selected by the user. When this "clear" icon is clicked, the value should be deleted and the field res ...

Upgrade Angular to the latest version in Visual Studio 2017

Embarking on a new journey with node, npm, and angular, I decided to dive into the book 'ASP NET CORE and Angular 5' by packet publishing. Ensuring I set up the environment correctly as per the book's instructions, I created a project with t ...

Exploring JSONPath in Cypress

I am currently working on extracting a JSON path for the specific HTML content with the language code DE Below is an example of the JSON data: { "name": "Name", "text": "", "html": "HTML content" ...

Eliminate the need to input the complete URL every time when making server calls

Currently, my springbok application has a React-Typescript frontend that is functioning well. I am using the request-promise library to make requests like this: get('http://localhost:8080/api/items/allItems', {json: true}). However, I would like ...

Select and activate a single input from multiple options in Angular

I have multiple input fields with corresponding buttons that enable the input when clicked. I would like the behavior of the buttons to work in such a way that when one button is clicked, only that specific input field is enabled while the others are disab ...

Is there a special function in AngularDart that gets triggered after a component has been rendered?

In my attempt to assess the scrollHeight and clientHeight property on a <div> element for determining whether to display a 'View more' link, I have encountered some obstacles: <div #clippedContainer class="clipped"> <some-other- ...

Utilizing Express, Request, and Node.js to manage GET requests in typescript

I'm struggling with using Express and Request in my project. Despite my efforts, the response body always returns as "undefined" when I try to get JSON data from the server. In my server.js file, this is the code snippet I have been working on: impo ...

Encountering Storage Access Problem on Android following upgrade to API 33

I am currently working on an Ionic, Angular, and Capacitor application where I am utilizing the Cordova-diagnostic-plugin to download images onto a device. However, since updating to Android API 33, I have encountered an issue. Issue Description: Once I ...

Deleting a particular item in Angular involves utilizing specific techniques for removal, while updating a

After connecting my reactive form app with a REST API, I encountered an issue while trying to delete a hotel. Instead of displaying the ID of the clicked hotel, it shows "Really delete the Hotel: (undefined)?" What could be causing this problem in my code ...

The browser is unable to load the Angular app's component

I'm having trouble with my index.html and main.ts files. The browser just displays "loading..." and doesn't load the component I created. Can someone please assist me? <link rel="stylesheet" href="../node_modules/bootstrap/dist/css/bootstrap. ...

Experiencing complications with an Angular 2 router

When a user logs into the system, they are greeted with a navigation bar featuring options like Dashboard, Customers, and Product. Below is an excerpt from my routes file: app.routing.ts export const router: Routes = [ { path: '', redir ...

Tips for accessing the value and text of an Angular Material mat-select through the use of *ngFor

When using a dropdown menu, I want to retrieve both the value and text of the selected option. View dropdown image Underneath the dropdown menu, I aim to display values in the format of "options: 'value' - 'selected option'". compone ...

Utilize the VSCode debugger to troubleshoot a .NET Core application through debugging with Visual Studio's IIS Express

My current setup involves an Angular app with .NET Core in the backend and Angular in the frontend. While my team prefers using Visual Studio 2019 for working on the backend, I personally find VSCode more suitable for Angular development. The challenge ari ...

Using Handlebars.js with Angular CLI versions 6 and above: A Step-by-Step Guide

Looking to create a customizable customer letter in either plain text or HTML format that can be edited further by the customer. Considering using Handlebars.js to render an HTML template with mustache tags, using a JSON object for business information. T ...

Angular component equipped with knowledge of event emitter output

I have a custom button component: @Component({ selector: "custom-submit-button" template: ` <button (click)="submitClick.emit()" [disabled]="isDisabled"> <ng-content></ng-content> </butto ...

Creating a Chrome extension with Angular 5: A comprehensive guide

Currently, I am in the process of developing a Chrome extension using Angular 5. Initially, I successfully created a basic Angular app with the help of Angular Material and it functioned perfectly as an Angular application (I used ng build for verification ...