Skip to content

Commit 9e7fe24

Browse files
committed
fix(material/core): fix mat-error not rendering with Closure Compiler (#28405)
* fix(material/core): fix mat-error not rendering with Closure Compiler Fix Closure Compiler issue with mat-error. Fix issue where mat-error does not render even when there is an error. Existing behavior is that _ErrorStateTracker sometimes reports error state as false when there is an error. This happens because Closure Compiler renames the _ErrorStateTracker's ErrorStateMatcher. The compiler renames all the other implementations of ErrorStateMatcher, but they have different names. Causes the matcher to be null in _ErrorStateTracker. Since ErrorStateMatcher is used as a class in some situations, Closure Compiler is not aware that it is intended to be the same type as the other implementations of ErrorStateMather. Fix issue by declaring ErrorStateMatcher as an interface. When this commit applied, mat-error will render when built with Closure Compiler. Googlers: see [internal issue report](b/316413299) * !fixup fix(material/core): fix mat-error not rendering with Closure Compiler (cherry picked from commit 6c49372)
1 parent 556c8b9 commit 9e7fe24

File tree

2 files changed

+8
-8
lines changed

2 files changed

+8
-8
lines changed

src/material/core/common-behaviors/error-state.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,12 @@
88

99
import {AbstractControl, FormGroupDirective, NgControl, NgForm} from '@angular/forms';
1010
import {Subject} from 'rxjs';
11-
import {ErrorStateMatcher} from '../error/error-options';
11+
import {ErrorStateMatcher as _ErrorStateMatcher} from '../error/error-options';
1212
import {AbstractConstructor, Constructor} from './constructor';
1313

14+
// Declare ErrorStateMatcher as an interface to have compatibility with Closure Compiler.
15+
interface ErrorStateMatcher extends _ErrorStateMatcher {}
16+
1417
/** @docs-private */
1518
export interface CanUpdateErrorState {
1619
/** Updates the error state based on the provided error state matcher. */
@@ -62,10 +65,7 @@ export class _ErrorStateTracker {
6265
const parent = this._parentFormGroup || this._parentForm;
6366
const matcher = this.matcher || this._defaultMatcher;
6467
const control = this.ngControl ? (this.ngControl.control as AbstractControl) : null;
65-
// Note: the null check here shouldn't be necessary, but there's an internal
66-
// test that appears to pass an object whose `isErrorState` isn't a function.
67-
const newState =
68-
typeof matcher?.isErrorState === 'function' ? matcher.isErrorState(control, parent) : false;
68+
const newState = matcher?.isErrorState(control, parent) ?? false;
6969

7070
if (newState !== oldState) {
7171
this.errorState = newState;

tools/public_api_guard/material/core.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ export interface CanDisableRipple {
7272
// @public
7373
export interface CanUpdateErrorState {
7474
errorState: boolean;
75-
errorStateMatcher: ErrorStateMatcher;
75+
errorStateMatcher: ErrorStateMatcher_2;
7676
updateErrorState(): void;
7777
}
7878

@@ -136,9 +136,9 @@ export class ErrorStateMatcher {
136136

137137
// @public
138138
export class _ErrorStateTracker {
139-
constructor(_defaultMatcher: ErrorStateMatcher | null, ngControl: NgControl | null, _parentFormGroup: FormGroupDirective | null, _parentForm: NgForm | null, _stateChanges: Subject<void>);
139+
constructor(_defaultMatcher: ErrorStateMatcher_2 | null, ngControl: NgControl | null, _parentFormGroup: FormGroupDirective | null, _parentForm: NgForm | null, _stateChanges: Subject<void>);
140140
errorState: boolean;
141-
matcher: ErrorStateMatcher;
141+
matcher: ErrorStateMatcher_2;
142142
// (undocumented)
143143
ngControl: NgControl | null;
144144
updateErrorState(): void;

0 commit comments

Comments
 (0)