Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error: Uncaught (in promise): Error: Datepicker: value not recognized as a date object by DateAdapter. #6773

Closed
uvconnects opened this issue Aug 31, 2017 · 23 comments

Comments

@uvconnects
Copy link

Bug, feature request, or proposal:

Json format.
Error: Uncaught (in promise): Error: Datepicker: value not recognized as a date object by DateAdapter.

What is the expected behavior?

{ "ID": 9, "8ID": 1209, "Date": "08-03-2017"}

What is the current behavior?

#### What are the steps to reproduce?

Providing a Plunker (or similar) is the best way to get the team to see your issue.
Plunker template: https://goo.gl/DlHd6U

What is the use-case or motivation for changing an existing behavior?

Which versions of Angular, Material, OS, TypeScript, browsers are affected?

Is there anything else we should know?

@julianobrasil
Copy link
Contributor

From what I got from your text, you're trying to set the datepicker with a string. You need to build a javascript Date object before assigning it to the input associated to the md-datepicker. Something like:

  ....

  const str: string[] = myJson.Date.split('-');
  this.myDateObject = new Date(+str[2], +str[1], +str[0]);

  ...
  <md-form-field>
    <input mdInput [(ngModel)]="myDateObject" [mdDatepicker]="picker">
  </md-form-field>
  <md-datepicker #picker></md-datepicker>

@parys
Copy link

parys commented Sep 1, 2017

Ok, but how about reactiveForms?

    private initUserEditForm(): void {
        this.userEditForm = this.formBuilder.group({
            'birthday': [null],
            'fullName': [""]
        });
    }

private parse(item: User): void {
        this.userEditForm.patchValue(item);
    }

And view:

<md-form-field>
            <input mdInput [mdDatepicker]="datePicker" formControlName="birthday">
            <md-datepicker-toggle mdSuffix [for]="datePicker"></md-datepicker-toggle>
        <md-datepicker #datePicker startView="year" touchUi="true"></md-datepicker>
        </md-form-field>

Now I should put value to each control manually and for date throung new Date(MyValue) ?
That's not cool, and adds additional code for support this approach. Or I didn't properly catch this approach? Please, somebody clarify: am I wrong?

@willshowell
Copy link
Contributor

@parys just use null to initialize the controls

@parys
Copy link

parys commented Sep 1, 2017

@willshowell but if I want to edit existing value? For new value it's OK to init via null.

@willshowell
Copy link
Contributor

IIRC, yes. You can set it as null and then reassign it (programmatically or through the datepicker) at a later time.

@julianobrasil
Copy link
Contributor

julianobrasil commented Sep 1, 2017

@parys, you'd have to parse the date in User item before patch it. You can redefine the Date in User object from string to any so you can do something like:

private parse(item: User): void {
        const str: string[] = item.Date.split('-');
        item.Date = new Date(+str[2], +str[1], +str[0]);

        this.userEditForm.patchValue(item);
    }

@parys
Copy link

parys commented Sep 1, 2017

Thanks for answer. But it's very sad. Now I should manually assign all controls(and their count maybe up to 10 where one or two of them are dateTime values) to avoid error that I tried to init Date value as string(but in model it's date(I don't know whether this ts/js limitation for checking type).

UPD: For now I'm getting value like this 2017-09-01T11:54:15.0156668+02:00 so I need to parse it again throung user.birthday = new Date(user.birthday) based on that I'm getting string value from my service in spite of I have Date field in my model?

@julianobrasil
Copy link
Contributor

@parys, you can override parse function in nativedateadapter to accept whatever you want.

@willshowell
Copy link
Contributor

willshowell commented Sep 1, 2017

@parys sorry I misread your prev. comment. What you're saying is correct, and yes it is annoying.

To restate: Sometimes you need to initialize or patch a form from a JSON object (ajax call, etc) and you must find all the dates and convert them to date objects before setting the value. This can be particularly cumbersome when the form value is deeply nested or has a previously unknown number of date properties.

@julianobrasil you know more about date adapters than me, is this something that can be automatically setup if I know I'll have a consistent string format coming from my API?

EDIT: Looks like it, thanks

@julianobrasil
Copy link
Contributor

julianobrasil commented Sep 1, 2017

@parys, you can take a look at this old plunk I had to work with string dates in 'dd/MM/yyyy' format: https://plnkr.co/edit/Ie0vYf?p=preview

Unfortunately, the plunks are temporarily broken after beta.10 release, but you can see the custom-date-adapter.ts file and the modifications in main.ts module imports:

providers: [{provide: DateAdapter, useClass: CustomDateAdapter }]

@uvconnects
Copy link
Author

that works fine but this means if I have array of multiply object property's, I cannot include it in my array I have to separate it, then when I update my array of object property's I have to push or Object assign this separate property to my array.

@julianobrasil
Copy link
Contributor

@Sevensnake, try the CustomDateAdapter aproach.

@uvconnects
Copy link
Author

works this way. thanks
const str: string[] = responses["Date"].split('-');
this.myDateObject = new Date(+str[2], +str[1], +str[0]);
this.Listnew["Date"] = this.myDateObject;
console.log('mydate', this.myDateObject);

@ghd8
Copy link

ghd8 commented Sep 1, 2017

see also the discussion in #6265 (comment)

@gdbaskara
Copy link

"date": {
"start": "2017-09-04T17:00:00.000Z",
"end": "2017-09-05T17:00:00.000Z"
}
i got this json, it's already date format but when i try to get it to the input in datepicker so, i can edit another date it's just not recognized as date value. I got the same error as this. any help?

@parys
Copy link

parys commented Sep 5, 2017

@gdbaskara
as mentioned above you have two options:
1 for each fields do this before patching control, for example: date.start = new Date(date.start);
2 use modified dateAdapter as julianoBrasil proposed
providers: [{provide: DateAdapter, useClass: CustomDateAdapter }]

@Toub
Copy link

Toub commented Sep 12, 2017

@parys looks like solution2 won't work as parse method is now called only if input is of type string: #6335

@parys
Copy link

parys commented Sep 12, 2017

@Toub I'm only repeated answer which mentioned above(tried to summarize). I'm using the first way. So I don't know whether the second approach has issues. Sorry, if I confused you :(

@julianobrasil
Copy link
Contributor

julianobrasil commented Sep 12, 2017

@Toub, the answer pointed by #6335 doesn't invalidate the possibility of using a CustomDateAdapter. Just says that, by default, the NativeDateAdapter uses only Date object from now on.

I updtated material in the plunk I've linked above and it works fine with string dates: https://plnkr.co/edit/Ie0vYf?p=preview

Edited: Unless you are talking about the control.setValue(). In that case, yes, it has to be a Date object.

@Toub
Copy link

Toub commented Sep 12, 2017

@julianobrasil Looks like the NativeDateAdapter is able to parse integers: https://github.com/angular/material2/blob/2.0.0-beta.10//src/lib/core/datetime/native-date-adapter.ts

So I guess it means that the DatePicker implementation does not call adapter.parse() if the input value is not a string.

However, I can't confirm as I can't find where it is implemented.

Edited: right I was talking about setting the value.

@julianobrasil
Copy link
Contributor

julianobrasil commented Sep 12, 2017

@Toub, in previous versions, the parse() function was called a lot! Now, if I get it right, it is called when:

  1. the date is set by the input (twice)
  2. the date is set by the calendar (twice)
  3. you open the calendar (once)

Internally it is called twice when you change date (i gess it's because it sets the input value and the calendar value, but haven't taken a look yet) and once every time the calendar is opened.

And it is not called when you use control.setValue().

@Toub
Copy link

Toub commented Sep 12, 2017

Ok. Thanks @julianobrasil for clarification!

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 7, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants