Angular 6 Date format MM/dd/yyyy in reactive form
Asked Answered
G

7

8

I am using Angular 6 with reactive forms and I am trying to figure out how to format the date value returned from a webapi. The date is displaying as 1973-10-10T00:00:00 and I want to format it to 10/10/1973. Below is the code to retrieve the data and display it. The webapi json dob value is 1973-10-10T00:00:00. The dob value in the model is of type Date.

html

<input formControlName="dob" type="text" [value]="dob | date: 'MM/dd/yyyy'" class="form-control" />

binding form

this.userInfoForm = this.fb.group({
      'userId': ['', [Validators.required]],
      'dob': ['', [Validators.required]]
});

loading saving

this.as.accountUserInfo(this.activeRoute$.ActiveUserId).subscribe(data => {
      this.userInfoModel$ = data as UserInfoModel;
      this.userInfoForm.patchValue(this.userInfoModel$);
});

api call

accountUserInfo(userId: number) {
return this.http.post(this.url + "UserInfo", userId)
.pipe(
  retry(3),
  catchError(this.handleError)
)}

I appreciate any help or guidance as how to transform the date to the MM/dd/yyyy format. Setting the html to date value does make it look ok but I don't want to use the built in browser date displays so I need to convert it to a string.

Thanks in advance.

Gassing answered 29/7, 2018 at 20:26 Comment(4)
after you have use date pipe what is the resultBigotry
Nothing changes. The date still displays as 1973-10-10T00:00:00. I even tried forcing a static value of [value]='01/01/2000' and it is still 1973-10-10T00:00:00.Gassing
Here's a better solution than the one accepted #39608068Sizemore
This other stackoverflow helped me: #45330819Engrossment
R
-2

This works for me : I patchValue the form with a transformed date using this function

fromJsonDate(jDate): string {
  const bDate: Date = new Date(jDate);
  return bDate.toISOString().substring(0, 10);  //Ignore time
}

In the form ( reactive forms ) I use :

<input type="date" formControlName="dob" class="form-control">  // No value

The browser shows the built in date picker and formats the date according to User operating system settings.

Then to post (save) values to the web api I transform again using :

toApiDate(bDate) {
  const apiDate: string = new Date(bDate).toUTCString();
  return apiDate;
}

I Use toUTCString() because my users may not be in the same timezone as my server ( in fact I am not ).

Riobard answered 29/7, 2018 at 21:57 Comment(2)
This lead me down the right path to get it working. I ended up removing the value in the html. I had suspected, and SiliconSoul confirmed, the value is overwritten by reactive forms. I ended up just adding a patch value for the dob after I patched the whole object. this.userInfoForm.patchValue(this.userInfoModel$); if (this.userInfoModel$ != null) { this.userInfoForm.patchValue({ dob: this.dp.transform(this.userInfoModel$.dob, 'MM/dd/yyyy') }); }Gassing
If the date isn't changed by the user, you are losing the time component of the original date.Sizemore
S
4

Had that same problem when using datepicker. The solution was simple: Change the input type to "date"

Before:

<input type="text" class="form-control" placeholder="dd/mm/yyyy"
            formControlName="inputNascimento" ngbDatepicker #d="ngbDatepicker">

After:

<input type="date" class="form-control" placeholder="dd/mm/yyyy"
            formControlName="inputNascimento" ngbDatepicker #d="ngbDatepicker">
Sassenach answered 21/11, 2018 at 0:35 Comment(0)
T
2

It won't matter what is set with the value binding because you have specified the formControlName which will override any existing value. Seems like you can use the DatePipe to format the date when it is set to the FormGroup: https://stackblitz.com/edit/angular-3tp7yz?file=src%2Fapp%2Fapp.component.ts

Trawl answered 29/7, 2018 at 22:8 Comment(2)
I am using an observable object so I do not have the option to load it in line like this.Gassing
THis approach worked for me. I only hate that you lose the original date value. It would be nice to have a displayValue which is piped, and actualValue containing the value before the pipe transform. Ofcourse, there are ways with hiding/manipulating form data but it would be nice to have a displayValue that can be altered on a form levelHeloise
N
2

In my case in Angular 13.2 I have similar issue while binding Date field to form.. It's probbably by diferences in locale date formats.. In Json data of model I have date in format

yyyy-MM-ddThh:mm:ss

But web browser displays date picker field like this

MM/dd/yyyy

After many probes, I find that this works:

<input type="date" #purchaseDate="ngModel" class="form-control" placeholder="yyyy-MM-dd" [ngModel]="vehicle.purchaseDate | date:'yyyy-MM-dd'" (ngModelChange)="vehicle.purchaseDate=$event" name="purchaseDate" >

So, display format is strange, and diferent with my regional settings in windows, but field id binded correctly.

Narcoanalysis answered 2/3, 2022 at 14:19 Comment(0)
K
1

You can transform the date format when you subscribe it, since date pipe operator does not work in formControlName.

this.as.accountUserInfo(this.activeRoute$.ActiveUserId).subscribe(data => {

      this.userInfoModel$ = data as UserInfoModel;
var datePipe=new DatePipe("en-US");

this.userInfoModel$.dob=datePipe.transform(this.userInfoModel$.dob,'MM/dd/yyyy');

      this.userInfoForm.patchValue(this.userInfoModel$);
});


<input formControlName="dob" type="text" class="form-control" />

Hope it helps!

Kella answered 24/9, 2018 at 10:56 Comment(0)
P
0

If you want different date time formats go with momentjs

Momentjs works fine with angular all versions and give different type of formats

first import momentjs like this:

import * as moment from 'moment';

If you want to pass your own format that also you can pass like

sysdate = moment().format('MMMM Do YYYY, h:mm a');

and the momentjs link below here

momentjs

Precursory answered 30/7, 2018 at 6:53 Comment(2)
Thanks for sharing that library. It looks really useful but my problem wasn't how to format a date but rather how to push the format to the view.Gassing
You shouldn't use moment anymore. It's not immutable and the bundles are too big. Use date-fns, day.js etc.Malda
H
0

I ended up using a second hidden input for the formControlName:

     <mat-form-field>
        <mat-label>Start Date</mat-label>
        <input type="text"
          #start
          matInput
          value="{{startDate | date: 'mediumDate'}}"
          autocomplete="off"
          placeholder="Start Date"
          attr.aria-label="Start Date"
          (keyup.enter)="changeDate(start.value, 'start')"
          (blur)="changeDate(start.value, 'start')">
      </mat-form-field>

      <input hidden formControlName="startDate">
Hexachord answered 6/9, 2019 at 6:22 Comment(0)
R
-2

This works for me : I patchValue the form with a transformed date using this function

fromJsonDate(jDate): string {
  const bDate: Date = new Date(jDate);
  return bDate.toISOString().substring(0, 10);  //Ignore time
}

In the form ( reactive forms ) I use :

<input type="date" formControlName="dob" class="form-control">  // No value

The browser shows the built in date picker and formats the date according to User operating system settings.

Then to post (save) values to the web api I transform again using :

toApiDate(bDate) {
  const apiDate: string = new Date(bDate).toUTCString();
  return apiDate;
}

I Use toUTCString() because my users may not be in the same timezone as my server ( in fact I am not ).

Riobard answered 29/7, 2018 at 21:57 Comment(2)
This lead me down the right path to get it working. I ended up removing the value in the html. I had suspected, and SiliconSoul confirmed, the value is overwritten by reactive forms. I ended up just adding a patch value for the dob after I patched the whole object. this.userInfoForm.patchValue(this.userInfoModel$); if (this.userInfoModel$ != null) { this.userInfoForm.patchValue({ dob: this.dp.transform(this.userInfoModel$.dob, 'MM/dd/yyyy') }); }Gassing
If the date isn't changed by the user, you are losing the time component of the original date.Sizemore

© 2022 - 2024 — McMap. All rights reserved.