Angular2 filter table based on two inputs using custom pipe

1.7k Views Asked by At

I have a table in which two columns are dates represented as strings. I want to filter the table based on two inputs (which are populated by two ngb-datepickers, default value is null). Using a custom pipe I am currently getting console error Cannot read property '0' of undefined as well as my table not rendering to the page, none of the buttons work, and form validation doesn't work. I import my custom pipe into declarations in app.module.ts. Minimal code is included to show entire scope, let me know if anything is confusing or to include more.

mainpage.component.html:

<div>
  <label>Start Date:</label>
  <input type="text" [(ngModel)]="startDateValue">
</div>
  <label>End Date:</label>
  <input type="text" [(ngModel)]="endDateValue">
</div>
//'let idx=index' and 'let even=even' are used to change color of the rows but I took out that code. The 'onClick' function just takes the row and uses an EventEmitter to output it.
<tr *ngFor="let dPoint of theData | searchDates:startDateValue:endDateValue; let idx=index; let even=even;" (click)="onClick(dPoint, idx)">
  <td>{{dPoint.tDataPoint}}</td>
  <td>{{dPoint.tICCP}}</td>
  <td>{{dPoint.tStartDate}}</td>
  <td>{{dPoint.tEndDate}}</td>
</tr>

mainpage.component.ts:

@Component({
  selector: 'main-page',
  styleUrls: ['../app.component.css'],
  templateUrl: 'mainpage.component.html',
  providers: [DataTableService, DatePipe]
})

export class MainPageComponent implements OnInit {
  secondForm : FormGroup;
  theData:DataTable[] = [];

  constructor(fb: FormBuilder, private datePipe: DatePipe, private dataService: DataTableService, private cdRef:ChangeDetectorRef){
    this.secondForm = fb.group({
      'startDate' : [null, Validators.required],
      'endDate' : [null, Validators.required]
    }, {validator: this.endDateAfterOrEqualValidator})
  }

  getTable(): void {
    this.dataService.getTable().then(theData => this.theData = theData);
    this.cdRef.detectChanges();
  }
}

search-pipe.ts:

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

@Pipe({
  name: "searchDates"
})

//if I comment out the code inside the transform function, I get no console errors, all functionality previously mentioned that stopped working now does again, but my entire table still does not render
export class SearchPipe implements PipeTransform {
  transform(value, args?){
    let firstDate = new Date(args[0]);
    let secondDate = new Date(args[1]);
    //let [minDate, maxDate] = args;
    return value.filter(row => {
      return row.tStartDate >= firstDate && row.tEndDate <= secondDate;
    });
  }
}

I believe my issues are improper syntax/functionality in my transform function. I've seen similar issues like this but I can't seem to format it for my needs and am just too unfamiliar with Angular2, especially pipes.

2

There are 2 best solutions below

0
On BEST ANSWER

arg is not an array , is just the first thing after :

export class SearchPipe implements PipeTransform {
  transform(value, firstDate , secondDate , arg3 , arg4 ){

    return value.filter(row => {
      return row.tStartDate >= firstDate && row.tEndDate <= secondDate;
    });
  }
}
0
On

I hope this can help in your example as it was solution for my problem.

Try to reuse async buikd-in pipe to notify Angular to proceed form building only after promise resolving.

Your example may looks like:

<tr *ngFor="let dPoint of theData | async | searchDates:startDateValue:endDateValue; let idx=index; let even=even;" (click)="onClick(dPoint, idx)">
  <td>{{dPoint.tDataPoint}}</td>
  <td>{{dPoint.tICCP}}</td>
  <td>{{dPoint.tStartDate}}</td>
  <td>{{dPoint.tEndDate}}</td>
</tr>

But first you need to change your theData type - you need promise as return type

var theData: Promise<DataTable> = null;
this.theData = this.dataService.getTable();

So using this approach your repeater do not start proceessing your data until your promise will not be resolved. On this stage you will have your data and your searchDates pipe will not cause empty-data-exception.

Here is more details about this pipe https://angular.io/docs/ts/latest/api/common/index/AsyncPipe-pipe.html