0

I have a list of data. The data structure is one to many. Each parent has multiple child items. I try hide the duplicated parent items. But it turns out hiding all duplicated records. I follow the tutorial below. Help needed. Instead of removing whole record, i just want to hide parents item.

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 {}
Lee
  • 181
  • 1
  • 3
  • 22

1 Answers1

1

I probably would't use a pipe for this. Also I haven't really implemented separation of concerns.

see demo here and explanation below

I would first look at your app component and add two methods it:

One for sorting your data by the key (credit this method to this answer here ). This way it is easier to determine 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 determining if the last item in the list had the same parent as the current item in the list

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

next in your app component you want to make sure to initialize your account array. I did this before the constructor

account: any[];

then your constructor should look like this. Make sure to sort after the array has been filled.

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)); 
}

Finally your html template should look like this. feel free to change the tags to make it look better but this should produce like what you want. Here I would the index to keep track of where we are in the for loop and us the ngif directive to decide whether or not to show the parent depending of the 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>
overboard182
  • 190
  • 3
  • 17