How to Hide Parent Items in Angular 2 Using *ngFor

I am dealing with a data structure where each parent has multiple child items. I am trying to hide duplicate parent items, but accidentally ended up hiding all duplicated records instead. I followed a tutorial, but now I need help fixing this issue. I only want to hide the parent items, not remove the entire record.

My datatable:        Failed Results:            Expected Results:

Parent Child         Parent Child                  Parent Child 
Lee    123           Lee    123                     Lee    123
Lee    124           Rose   111                            124
Lee    125                                                 125
Rose   111                                          Rose   111

code:

 //our root app component
    import { Component, NgModule, VERSION } from '@angular/core'
    import { BrowserModule } from '@angular/platform-browser'
    import { Pipe, PipeTransform, Injectable } from '@angular/core'


    @Pipe({
        name: 'uniqFilter',
        pure: false
    })
    @Injectable()
    export class UniquePipe implements PipeTransform {
        transform(items: any[], args: any[]): any {
            // filter items array, items which match and return true will be kept, false will be filtered out

            return _.uniqBy(items, args);
        }
    }

    @Component({
      selector: 'my-app',
      providers: [],
      template: `
        <div>
                    <ul>
                        <li *ngFor="let account of accounts | uniqFilter:'Parent'">{{ account.Parent }} and {{ account.Child }}</li>
                    </ul>
        </div>
      `,
      directives: [],
      pipes: [UniquePipe]
    })
    export class App {
      constructor() {
          this.accounts = [{
              "Parent": 'Lee',
              "Child": "4/6/2016"
          },
          {
              "Parent": 'Lee',
              "Child": "4/7/2016"
          },

          {
              "Parent": 'Rose',
              "Child": "4/9/2016"
          },
          {
              "Parent": 'Rose',
              "Child": "4/10/2016"
          },

          {
              "Parent": 'Lee',
              "Child": "4/12/2016"
          }];
      }
    }

    @NgModule({
      imports: [ BrowserModule ],
      declarations: [ App, UniquePipe ],
      bootstrap: [ App ],
      providers: [ UniquePipe ]
    })
    export class AppModule {}

Answer №1

I wouldn't opt for using a pipe in this scenario, and I haven't yet incorporated the separation of concerns.

Take a look at the demo here along with the explanation below

To begin with, update your app component by adding two methods to it:

First method sorts your data based on the key (credit goes to this answer here). This helps in easily determining if a parent has been listed already

// sort on key values
 keysrt(key,desc) {
   return function(a,b){
   return desc ? ~~(a[key] < b[key]) : ~~(a[key] > b[key]);
   }
}

And another method that checks if the last item in the list had the same parent as the current item

lastParent(i){
    if(i>0){
      if (this.accounts[i].Parent === this.accounts[i-1].Parent)
        return false;
      else
        return true;
    }
    else
      return true;
}

Next, ensure to initialize your account array in the app component. It's recommended to do this before constructor

account: any[];

Then, modify your constructor accordingly. Remember to sort after filling the array.

constructor() {
      this.accounts = [{
          "Parent": 'Lee',
          "Child": "4/6/2016"
      },
      {
          "Parent": 'Lee',
          "Child": "4/7/2016"
      },

      {
          "Parent": 'Rose',
          "Child": "4/9/2016"
      },
      {
          "Parent": 'Rose',
          "Child": "4/10/2016"
      },

      {
          "Parent": 'Lee',
          "Child": "4/12/2016"
      }];

      this.accounts.sort(this.keysrt('Parent', true)); 
}

Lastly, adjust your HTML template like this. You can change the tags for better appearance, but this structure should give you desired output. Use index to track loop progress and ngIf directive to decide whether to display the parent based on lastParent function

<div>
     <ul>
         <li *ngFor="let account of accounts; let i = index">  
             <div *ngIf = "lastParent(i)">{{ account.Parent}}</div>
              and {{ account.Child }}
         </li>
     </ul>
</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

How can I remove the ID of the object data from the list?

When sending the data initially, there are no issues. However, when attempting to update, I am able to delete the root object's id but struggling to delete the ids of objects in the list. Any suggestions on what I can do? const handleSubmit = async ...

Executing asynchronous methods in a Playwright implementation: A guide on constructor assignment

My current implementation uses a Page Object Model to handle browser specification. However, I encountered an issue where assigning a new context from the browser and then assigning it to the page does not work as expected due to the asynchronous nature of ...

Ways to obtain the component reference when clicking in Angular 2?

<!--snippet from template file--> <custom-element ... other attributes (click)="handleClick()" </custom-element> @Component({ //selector and templateUrl }) class MainComponent{ handleClick(){ // Obtaining the re ...

How to use Angular2 Router to redirect a state to its default substate

How can we implement a default substate in the new Angular2 Router? For instance, I would like the router to automatically direct from /user to /user/profile, creating a default substate for user. ...

The value of type 'X' cannot be assigned to type 'Y' or 'undefined'

In my code, there is a component that requires a prop with an enum value: export enum AType { some = "SOME", word = "WORD", } const MyComponent = (arg: AType) => {} When I try calling this component like so: <MyComponent ar ...

Invoking a function within an Angular component

I am facing a problem - is there a way to invoke a function from the name.component.html file without using a button click, and without needing to go through the .ts file or service? ...

Mapping an array based on specific conditions

When using my photo gallery app, I faced a challenge in mapping an array of images based on the user-selected album name. The current setup works perfectly for the 'Cambodia' album where all images are correctly logged in the console after mappin ...

What is preventing me from retrieving a value from a member function or method within a TypeScript class instance?

I am facing an issue with the FileInfo class that implements the IFileInfo interface. This class has an instance member function ext and a function getExt(). Within my component, there is a private method named openTempFolder() which makes an HTTP call to ...

Showing object data in TypeScript HTML when the object property starts with a numeral

Below is the function found in the TypeScript file that retrieves data from an API: .ts file getMachineConfigsByid(id) { this.machinesService.getMachineConfigById(id).subscribe((res) => { if (res.status === 'success') { ...

React Typescript - Unexpected character ',' encountered at line 1005

Currently, I am utilizing Typescript within a React application that integrates with Graphql. Encountering an error: ',' expected.ts(1005) After researching possible solutions, most suggest that the issue might be due to using an outdated ve ...

Guide on enabling the Access-Control-Allow-Origin feature for Angular 5 and Node.js:

After exploring various methods to include 'Access-Control-Allow-Origin', I have not been successful in resolving the issue. I am utilizing the @angular/common/http module with an external URL as a data source. However, when attempting to retrie ...

I am facing an issue with the asynchronous function as it is displaying an error message

**I am facing an issue with displaying categories. I have attempted to do this using async function, however the data is not showing up** <div class="form-group"> <label for="category">Category</label> <select id="categor ...

Step-by-step guide on how to index timestamp type using Knex.js

I'm in the process of indexing the created_at and updated_at columns using knex js. However, when I try to use the index() function, I encounter the following error: Property 'index' does not exist on type 'void' await knex.sche ...

How can I retrieve routing parameters in a Vue.js/Nuxt/TypeScript app?

In the process of developing my website based on the Nuxt TypeScript Starter template, I've encountered a challenge. Specifically, I have created a dynamically routed page named _id.vue within my pages folder and am looking to access the id property i ...

Angular 2 Route offers a blueprint for creating a Component template

Is it possible to assign a specific template to a component within a route in Angular 2? I am working on a component that has the same controller functionality across three different views. My goal is to use the same component for all three views, but wit ...

Challenges associated with adding information to FormData in an Angular Net 5 Application

I'm currently working on developing an application using Angular 11 and .NET 5 and am facing some challenges while trying to implement the file upload feature. I have successfully managed to send pictures to the server, but I'm encountering issue ...

What causes the template to refresh when the input remains unchanged while employing the OnPush strategy?

Trying to understand this situation: @Component({ selector: 'app-test', template: `value: {{value|json}} <button (click)="setValue()">set</button>`, changeDetection: ChangeDetectionStrategy.OnPush }) export class TestComponent ...

The ngModel feature is not functioning properly when trying to update in tag inputs

I am having trouble with two-way data binding using ngModel in tag-inputs. Can someone please assist me? Here is the link to my code on StackBlitz ...

Developing an Observer and sending updates to my followers

I have a function that returns an Observer for subscription. Inside this function, I make an API call which also returns an Observer to which I subscribe. Once I analyze the data received from this Observer, I need to notify my own Observer subscribers. B ...

How can I convert duplicate code into a function in JavaScript?

I have successfully bound values to a view in my code, but I am concerned about the duplicate nested forEach loops that are currently present. I anticipate that Sonarcube will flag this as redundant code. Can anyone advise me on how to refactor this to avo ...