Suppose a component (inside the angular app) having several reactive forms containing datepickers (I'm using mat-datepicker
from angular material lib) and other inputs. After a user hit "Submit" button I send the value of forms to backed (with HttpClient.post
). The problem is that datepicker fields are serialized as "2020-11-18T22:00:00.000Z"
(obviously Date.toJSON()
method is called) while backend expects other format.
Note that I'm using formly
lib to build my forms, cause set of components on each form may vary. You might not be familiar with formly
but anyway set of datepickers may vary as well, so I can't convert datepicker fields directly cause I don't know the exact list of date fields in a place where I send the value of forms.
Is there an elegant solution to my problem? Can't think up something better than monkey-patching Date.prototype.toJSON()
or looping through objects sent on the server, check the type of fields and changing field if it's a Date
? I can't find a way to set the format of value output by datepicker either in material or in formly.
Implementing ControlValueAccessor would be an elegant solution. The idea is to create a date picker component that takes your date format as input and send back your format as output.
For that you just have to create a new component that I would call MatDatepickerWrapperComponent
for this example. The template of this component would be nothing more than the material date picker :
<mat-form-field appearance="fill">
<mat-label>Choose a date</mat-label>
<input matInput [matDatepicker]="picker" [(ngModel)]="model" (ngModelChange)="modelChange($event)">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
From the component side, you will have to implement ControlValueAccessor, and do the transformations you need :
writeValue(value: string): void {
this.model = transformDateFromMyFormatToIso(value);
}
modelChange(value: string) {
const transformedValue = transformIsoDateToMyFormat(value);
this.onChange(transformedValue);
}
You can now add the new component to a form the way you would have added the original one.