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

fix(datepicker): allow DateAdapter authors to have more control ove… #7346

Merged
merged 4 commits into from
Oct 30, 2017

Conversation

mmalerba
Copy link
Contributor

@mmalerba mmalerba commented Sep 26, 2017

…r what can/can't be coerced to a date

fixes #7286

BREAKING CHANGES:

  • fromIso8601 method on DateAdapter removed in favor of deserialize
  • DateAdapter implementations must now implement the invalid method

@mmalerba mmalerba added P1 Impacts a large percentage of users; if a workaround exists it is partial or overly painful pr: needs review labels Sep 26, 2017
@googlebot googlebot added the cla: yes PR author has agreed to Google's Contributor License Agreement label Sep 26, 2017
@mmalerba
Copy link
Contributor Author

mmalerba commented Oct 2, 2017

rebased

* null date (e.g. the empty string).
* @throws If the given value cannot be coerced to a valid date or null.
*/
coerceToDate(value: any): D | null {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't this need to align with toIso8601? I think the heart of what this is trying to do is the same as parse / format except that instead of being string that the user see / inputs, it's the formats that the backend sends / accepts. Looking at it that way, I think this would make sense:

parse / format -> for user-facing strings
serialize / deserialize -> for backend-facing strings (or JSON or whatever)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For user-facing strings: I agree we need both.

For backend-facing strings: I don't think the DateAdapter is particularly concerned with these for the most part. We don't really know if the dates coming into / out of the datepicker are going to the backend or some other part of the JS app, its up to the user to decide and handle that. However for convenience we might want to allow certain values (such as ISO 8601 strings or UNIX timestamps) to be automatically coerced into the proper type - similar to how we coerce "true" and "false" for boolean properties. This is what the new coerceToDate method is about, allowing the user to decide what can be coerced and what can't.

There's also a third class: DOM-facing strings. For example to set the min attribute on the input we need the date in a format that the DOM can understand, which is ISO 8601. This is why we always need to have a way to go from whatever the date type is to an ISO 8601 string.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do you feel, then, about calling this method deserialize?

Also on toIso8601, we should document somewhere why/how this is used.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

I'll update the description of all the to/from date methods to make sure its clear exactly what each one is used for

@mmalerba mmalerba force-pushed the dp-coerce branch 2 times, most recently from 9051f65 to 227e9c9 Compare October 11, 2017 22:58
@mmalerba
Copy link
Contributor Author

comments addressed

@@ -118,7 +118,7 @@ export abstract class DateAdapter<D> {
abstract today(): D;

/**
* Parses a date from a value.
* Parses a date from a user-inputted value.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

user-provided?

* the given value is already a valid date object or null. The `<mat-datepicker>` will call this
* method on all of it's `@Input()` properties that accept dates. It is therefore possible to
* support passing your wire format directly to these properties by overriding this method to
* also deserialize your wire format.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Say something like "This will generally be used for data coming directory from some backend or database." ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this just saying the same thing as the "wire format" part above?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, but it's a bit more explicit (less jargony?) than "wire format"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, re-worded it to say backend

@@ -192,6 +187,26 @@ export abstract class DateAdapter<D> {
abstract isValid(date: D): boolean;

/**
* Attempts to deserialize a value to a valid date object. This is different from parsing in that
* deserialize should only accept non-ambiguous, locale-independent values (e.g. a ISO 8601
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"locale-independent values" -> "locale-independent formats"?

Does the phrase "locale-independent" refer specifically to the format? E.g., ISO 8601 not a localized format, but it might not contain UTC

@mmalerba
Copy link
Contributor Author

done

@jelbourn jelbourn added merge: caretaker note Alert the caretaker performing the merge to check the PR for an out of normal action needed or note pr: lgtm action: merge The PR is ready for merge by the caretaker and removed pr: needs review labels Oct 12, 2017
@jelbourn
Copy link
Member

Caretaker note: will need to update APIs for folks that have their own adapter (at least one).

@mmalerba mmalerba force-pushed the dp-coerce branch 2 times, most recently from 84fc26d to 8166e61 Compare October 13, 2017 18:01
@mmalerba
Copy link
Contributor Author

Instantly throwing when deserialization fails may be a little harsh. I think I'll rework this to return an invalid date or something

@mmalerba mmalerba removed the action: merge The PR is ready for merge by the caretaker label Oct 24, 2017
…r what can/can't be coerced to a date

BREAKING CHANGES:
- `fromIso8601` method on `DateAdapter` removed in favor of `coerceToDate`
@mmalerba
Copy link
Contributor Author

@jelbourn made some changes, PTAL

Copy link
Member

@jelbourn jelbourn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@jelbourn jelbourn added pr: lgtm action: merge The PR is ready for merge by the caretaker labels Oct 27, 2017
@mmalerba mmalerba merged commit 9fa075e into angular:master Oct 30, 2017
@Elkrival
Copy link

Elkrival commented Nov 1, 2017

@mmalerba Thank you for the adapter example code, it asserts the methods to implementing MomentJS to the Datepicker Module.

I am adding the DatePickerModule to my current project, when implementing the new changes from the DateAdapter example code, I keep running into an error in line 242 where return super.deserialize(value) is not found in the Moment export instance. As a workaround I reverted back to the code before the deserialize() function was added.

A thousand thank you's for the example, we love the material2 library, and my designer friend Chandan loves the Material Design standard.

@mmalerba mmalerba deleted the dp-coerce branch July 31, 2018 21:19
@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 9, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: merge The PR is ready for merge by the caretaker cla: yes PR author has agreed to Google's Contributor License Agreement merge: caretaker note Alert the caretaker performing the merge to check the PR for an out of normal action needed or note P1 Impacts a large percentage of users; if a workaround exists it is partial or overly painful
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Feature Request: Allow custom coerceDateProperty strategy
4 participants