Search code examples
validationdateangulardatepickerangular2-pipe

Prevent angular2 app from crashing due to invalid date (maybe override DatePipe?)


I basically have an HTML5 date picker like this:

<input class="form-control" type="date" [(ngModel)]="startDate" />

And another area that displays the date from the model like this:

{{startDate | date:shortDate}}

I don't think it's relevant to this question but to be thorough, I have this kind of thing behind the scenes:

private startDate: string;
private endDate: string;

updateDateFilter() {
    let from = new Date(this.startDate);
    let to = new Date(this.endDate);
    **Stuff to filter based on date range**
}

It's awesome. There's a lot more going on but it'd probably be extraneous detail.

The trouble is you can click into the date picker and, say, select the year and hit delete which does this:

Bad Date

No problem right? Wrong, because the Angular2 date pipe gets confused and my whole app crashes after displaying this surprisingly helpful error message:

ORIGINAL EXCEPTION: Invalid argument '' for pipe 'DatePipe'

The solution seems simple but I'm not sure how to go about it. I'm thinking I just need to catch the date string before it's processed by the DatePipe and make sure there's valid content for the day, month, and year. But Angular2 does magic and the since it's done using model binding I don't see a clear route to intervention.

I probably need to override the DatePipe, keeping its functionality but checking the string first. I don't know how. If you know how to do that, do share. Any alternative approaches would be helpful too. I just can't have the app crash whenever the date is incomplete.

Thanks!


Solution

  • You could create your own pipe and either extend the default DatePipe or just instantiate it and call it programmatically.

    @Pipe({
      name: 'customDate'
    })
    export class CustomDatePipe extends DatePipe {
      transform(date: string, pattern?: string): string {
        // validate/initialize date
        return super.transform(date, pattern);
      }
    }
    

    Or the second case:

    export class CustomDatePipe {
      private datePipe: DatePipe = new DatePipe();
    
      transform(date: string, pattern?: string): string {
        // validate/initialize date
        return this.datePipe.transform(date, pattern);
      }
    }
    

    Did not had the chance to check this but I assume both approaches should work.