Using Angular2's *ngIf and *ngFor can result in the generation of numerous empty elements

I am currently working with two tables in my database, and using APIs to create loops:

<div *ngFor="let laptop of laptops">
    some content
    <!-- Producer / Name -->
    <div *ngFor="let producer of producers">
         <div class="title" *ngIf="producer.id === laptop.producerId>
               {{producer.name}} {{laptop.model}}
         </div>

    </div>
</div>

I have a total of 70 producer names and a foreign key linking laptops to the producer table. For example, if my laptop has a producerId value of 3, I want to loop through each producer and only display those that meet the condition. The current implementation is functional, but the resulting DOM structure with 70 divs is concerning. I came across this SO post: *ngIf and *ngFor on same element causing error

In response to the above issue, I adjusted my code as follows:

 <ng-container *ngFor="let producer of producers>
        <div class="title" *ngIf="producer.id === laptop.producerId>
             {{producer.name}} {{laptop.model}}
        </div>
</ng-container>

The resulting DOM now looks like this:

https://i.sstatic.net/nCgnw.png

Is this the correct approach? Or is there a more efficient way to only create the necessary div elements based on the condition? https://i.sstatic.net/KN4MO.png

Answer №1

As mentioned by @Gunter, these placeholders are created for binding purposes which is a common practice.

Personally, I prefer to organize my data before generating the HTML code to ensure better performance and readability.

// once the laptops and producers are fetched from the server, call the method below
formatLaptopData(producers) {
    this.laptops = this.laptops.map((laptop: any)=> {
       laptop.producers = 
           producers.filter((producer: any) => laptop.producerId == producer.id);
       return laptop;
    });
}

HTML

<div *ngFor="let laptop of laptops">
    some content
    <div *ngFor="let producer of laptop.producers">
         <div class="title">
              {{producer.name}} {{laptop.model}}
         </div>
    </div>
</div>

Answer №2

To achieve this, you can implement a filter by creating a new file called FilterPipe.ts containing the following code:

import {Pipe, PipeTransform} from '@angular/core';

@Pipe({
  name: 'filter'
})
export class FilterPipe implements PipeTransform {
public transform(value, keys: string, term: any) {
 if (!term) return value;
  return (value || []).filter(item => keys.split(',').some(key => 
  item.hasOwnProperty(key) && new RegExp(term, 'gi').test(item[key])));
 }
}

Your modified code snippet will look like this:

<div *ngFor="let laptop of laptops">
some content
<!-- Producer / Name -->
  <div class="title" *ngFor="let producer of producers | filter : 'id' : laptop.producerId">
           {{producer.name}} {{laptop.model}}
  </div>
</div>

Remember to import the filter into your module.

Answer №3

After going through the entire response, I managed to discover the solution in the end. All you have to do is include ;else null within the ngIf*

<div *ngFor="let producer of producers">
     <div class="title" *ngIf="producer.id === 'laptop.producerId'; else null">
           {{producer.name}} {{laptop.model}}
     </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

Why does WebStorm fail to recognize bigint type when using TSC 3.4.x?

Currently, I am working on the models section of my application and considering switching from using number to bigint for id types. However, despite knowing that this is supported from TSC 3.2.x, WebStorm is indicating an error with Unresolved type bigint. ...

Is it possible for TypeScript to deduce the type of a discriminated union using "extracted" boolean logic?

Recently, I've been using discriminated unions (DU) more frequently and have really started to appreciate their benefits. However, I've encountered a challenge that I can't seem to resolve. When I include a boolean check inline for the DU, T ...

I recently made the switch to Angular 9.0 for my project, but when I ran the build using yarn, I encountered some warnings. Despite the

I encountered this issue on both Ubuntu 16.04 and 18. I have tried various solutions such as reinstalling yarn, node, and clearing the cache, but the warnings persist. For every build using a script, the node_modules folder is deleted and then reinstalled ...

ASP.NET is being used to host an angular application, but the deployUrl feature is

I have a .NET 6.0 ASP.NET application where I've set up a route /ngxapp to serve my Angular 13 application. The Angular app is stored in the wwwroot/ngxapp folder, as shown below. I've been using this code for years to deliver the Angular app: ...

What limitations do we face when trying to change the objects received by a component through @input() in Angular?

Recently, I made the leap from angular 7 to angular 11 in my app. Everything was running smoothly until I decided to incorporate angular universal for server-side rendering. Shortly after implementing server-side rendering, a flurry of errors cropped up, ...

Error code 2769 in Typescript occurs when attempting to transfer process information to the data state in order to utilize it within a modal

I'm encountering an issue while trying to pass a process to a setData state from a .map function in order to display it on a modal. The error message I'm receiving is: "No overload matches this call. Overload 1 of 2, '(props: { compone ...

Enhancing Mongoose promises with Bluebird in a TypeScript environment

Currently, I am working on a project that involves developing an application using nodejs/typescript and a mongodb database. In order to interact with the database, I have implemented mongoose as my query interface. Recently, I came across an informative ...

Implementing a variable for an array in Angular 4: A step-by-step guide

I need help determining the correct value for skill.team[variable here].name in Angular, where all team names are retrieved from the skill. Below is the code snippet: HTML <select [(ngModel)]="skill.teams[1].name" name="teamName" id="teamName" class= ...

Adjusting Size Dynamically for Tooltips Based on Content Length

In my angular app using ng-bootstrap v4.2.1 on an older codebase, I have successfully created a tooltip with some very long sentences as content. I am trying to make the tooltip 800px wide, but when I set the width, only the first few words fill the space. ...

Construct this node project utilizing either gulp or webpack exclusively

In the structure of my project, you will find various folders like node, build, gulp, and src. These folders contain important files for the development process such as .gitignore, gulpfile.js, package.json, tsconfig.json, webpack.config.js, server.js, con ...

Trigger Change Detection once Angular Material matDialog is closed

Within my parent component, I have two child components: FilterBookmarksComponent and ManageBookmarksSidebar. The FilterBookmarksComponent features an Angular Material Dropdown that dynamically updates the list of filters below it based on the user's ...

Pictures are not visible on mobile devices

Currently, I am utilizing Ionic 2 for my project. While the images are displaying correctly on the browser, they are not showing up on the device. This issue has been perplexing me. I attempted to resolve this problem by using the following code: <i ...

The attribute 'nodeQuery' is not found within the type '{}'

While working on a project with Angular and Apollo, I encountered an issue when trying to build the application using ng build. Despite functioning correctly on localhost:4200, I faced errors during the build process. The app communicates with a GraphQL se ...

Implementing Login using Google in a Nativescript iOS application: A step-by-step guide

I've been working on implementing Google's ID provider login in Nativescript using the nativescript-social-login plugin. While it works smoothly on Android, I've hit a roadblock with iOS. Following the instructions from the plugin creator, ...

Ways to indicate a mat-checkbox as selected in Angular 7

I recently integrated a mat-checkbox into my project. To set the mat-checkbox as checked, I attempted to use [checked]="true" <div *ngFor="let dwidgets of module.widgets"> <mat-checkbox [formControl]="moduleswidgets.controls['widgets' ...

How to activate form autofill in an Angular app

After migrating my app to Angular, I noticed that the form no longer autocompletes upon returning page visits. However, everything else seems to be working perfectly fine. I have a hunch that this issue is related to the *ngIf template expressions and the ...

A guide on streamlining the process of generating "this." variables within Angular

When it comes to working with Javascript, particularly Angular, I find myself using the this. syntax quite often. I'm curious to know if it's possible to concatenate variables in order to create a this. variable. For instance, is this achievab ...

Display error messages upon submitting the form

I am currently working on an Angular 6 Form with validation. My main goal is to display error messages only after the form has been submitted. It is crucial that these messages remain constant while the user types in the input field. For instance, if a use ...

Mastering Interpolation in React with TypeScript is essential for creating dynamic and interactive UI components. By leveraging the

Incorporating and distributing CSS objects through ChakraUI presents a simple need. Given that everything is inline, it seems the main issue revolves around "& > div". However, one of the TypeScript (TS) errors highlights an unexpected flagging of ...

Achieving Bi-Directional Data Binding with Vue.js using the vue-property-decorator Library

Currently, I am working with Vue.js and TypeScript while also utilizing the vue-property-decorator. My goal is to establish two-way data binding between a parent and child component. Below is an example of what I have in mind: Parent Component <templa ...