Skip to content

Commit

Permalink
fix(angular): null values are not converted to falsy value (#26341)
Browse files Browse the repository at this point in the history
BREAKING CHANGE:

Datetime:

Passing the empty string to the `value` property will now error as it is not a valid ISO-8601 value.

Angular:

`null` values on form components will no longer be converted to the empty string (`''`) or `false`. This impacts `ion-checkbox`, `ion-datetime`, `ion-input`, `ion-radio`, `ion-radio-group`, ion-range`, `ion-searchbar`, `ion-segment`, `ion-select`, `ion-textarea`, and `ion-toggle`.
  • Loading branch information
liamdebeasi committed Nov 23, 2022
1 parent 1e855e7 commit ce2e37b
Show file tree
Hide file tree
Showing 6 changed files with 21 additions and 16 deletions.
7 changes: 7 additions & 0 deletions BREAKING.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ This is a comprehensive list of the breaking changes introduced in the major ver
- [Types](#version-7x-types)
- [Overlay Attribute Interfaces](#version-7x-overlay-attribute-interfaces)
- [JavaScript Frameworks](#version-7x-javascript-frameworks)
- [Angular](#version-7x-angular)
- [React](#version-7x-react)
- [Vue](#version-7x-vue)
- [Utilities](#version-7x-utilities)
Expand Down Expand Up @@ -101,6 +102,8 @@ This section details the desktop browser, JavaScript framework, and mobile platf

- Datetime no longer incorrectly reports the time zone when `value` is updated. Datetime does not manage time zones, so any time zone information provided is ignored.

- Passing the empty string to the `value` property will now error as it is not a valid ISO-8601 value.

<h4 id="version-7x-input">Input</h4>

- `ionChange` is no longer emitted when the `value` of `ion-input` is modified externally. `ionChange` is only emitted from user committed changes, such as typing in the input and the input losing focus or from clicking the clear action within the input.
Expand Down Expand Up @@ -223,6 +226,10 @@ Any references to the virtual scroll types from `@ionic/core` have been removed.

<h2 id="version-7x-javascript-frameworks">JavaScript Frameworks</h2>

<h4 id="version-7x-angular">Angular</h4>

- `null` values on form components will no longer be converted to the empty string (`''`) or `false`. This impacts `ion-checkbox`, `ion-datetime`, `ion-input`, `ion-radio`, `ion-radio-group`, ion-range`, `ion-searchbar`, `ion-segment`, `ion-select`, `ion-textarea`, and `ion-toggle`.

<h4 id="version-7x-react">React</h4>

`@ionic/react` and `@ionic/react-router` no longer ship a CommonJS entry point. Instead, only an ES Module entry point is provided for improved compatibility with Vite.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export class BooleanValueAccessorDirective extends ValueAccessor {
}

writeValue(value: any): void {
this.el.nativeElement.checked = this.lastValue = value == null ? false : value;
this.el.nativeElement.checked = this.lastValue = value;
setIonicClasses(this.el);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,7 @@ export class ValueAccessor implements ControlValueAccessor, AfterViewInit, OnDes
constructor(protected injector: Injector, protected el: ElementRef) {}

writeValue(value: any): void {
/**
* TODO FW-2646
* Change `value == null ? '' : value;`
* to `value`. This was a fix for IE9, but IE9
* is no longer supported; however, this change
* is potentially a breaking change
*/
this.el.nativeElement.value = this.lastValue = value == null ? '' : value;
this.el.nativeElement.value = this.lastValue = value;
setIonicClasses(this.el);
}

Expand Down
12 changes: 9 additions & 3 deletions angular/test/base/e2e/src/inputs.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,15 @@ describe('Inputs', () => {

cy.get('ion-checkbox').should('have.prop', 'checked').and('equal', false);
cy.get('ion-toggle').should('have.prop', 'checked').and('equal', false);
cy.get('ion-input').should('have.prop', 'value').and('equal', '');
cy.get('ion-datetime').should('have.prop', 'value').and('equal', '');
cy.get('ion-select').should('have.prop', 'value').and('equal', '');
/**
* The `value` property gets set to undefined
* for these components, so we need to check
* not.have.prop which will check that the
* value property is undefined.
*/
cy.get('ion-input').should('not.have.prop', 'value');
cy.get('ion-datetime').should('not.have.prop', 'value');
cy.get('ion-select').should('not.have.prop', 'value');
});

it('should get some value', () => {
Expand Down
3 changes: 1 addition & 2 deletions core/src/components/datetime-button/datetime-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,7 @@ export class DatetimeButton implements ComponentInterface {
* to keep checking if the datetime value is `string` or `string[]`.
*/
private getParsedDateValues = (value?: string[] | string | null): string[] => {
// TODO FW-2646 Remove value === ''
if (value === '' || value === undefined || value === null) {
if (value === undefined || value === null) {
return [];
}

Expand Down
4 changes: 2 additions & 2 deletions core/src/components/datetime/datetime.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1171,7 +1171,7 @@ export class Datetime implements ComponentInterface {
}

private processValue = (value?: string | string[] | null) => {
const hasValue = value !== '' && value !== null && value !== undefined;
const hasValue = value !== null && value !== undefined;
const valueToProcess = hasValue ? parseDate(value) : this.defaultParts;

const { minParts, maxParts } = this;
Expand Down Expand Up @@ -1283,7 +1283,7 @@ export class Datetime implements ComponentInterface {
};

private hasValue = () => {
return this.value != null && this.value !== '';
return this.value != null;
};

private nextMonth = () => {
Expand Down

0 comments on commit ce2e37b

Please sign in to comment.