feat(common): better error message when non-template element used in NgIf (#22274)
closes #16410 PR Close #22274
This commit is contained in:
parent
49082d7ab2
commit
67cf11d071
|
@ -6,7 +6,7 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {Directive, EmbeddedViewRef, Input, TemplateRef, ViewContainerRef} from '@angular/core';
|
import {Directive, EmbeddedViewRef, Input, TemplateRef, ViewContainerRef, ɵstringify as stringify} from '@angular/core';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -118,6 +118,7 @@ export class NgIf {
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
set ngIfThen(templateRef: TemplateRef<NgIfContext>) {
|
set ngIfThen(templateRef: TemplateRef<NgIfContext>) {
|
||||||
|
assertTemplate('ngIfThen', templateRef);
|
||||||
this._thenTemplateRef = templateRef;
|
this._thenTemplateRef = templateRef;
|
||||||
this._thenViewRef = null; // clear previous view if any.
|
this._thenViewRef = null; // clear previous view if any.
|
||||||
this._updateView();
|
this._updateView();
|
||||||
|
@ -125,6 +126,7 @@ export class NgIf {
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
set ngIfElse(templateRef: TemplateRef<NgIfContext>) {
|
set ngIfElse(templateRef: TemplateRef<NgIfContext>) {
|
||||||
|
assertTemplate('ngIfElse', templateRef);
|
||||||
this._elseTemplateRef = templateRef;
|
this._elseTemplateRef = templateRef;
|
||||||
this._elseViewRef = null; // clear previous view if any.
|
this._elseViewRef = null; // clear previous view if any.
|
||||||
this._updateView();
|
this._updateView();
|
||||||
|
@ -163,3 +165,10 @@ export class NgIfContext {
|
||||||
public $implicit: any = null;
|
public $implicit: any = null;
|
||||||
public ngIf: any = null;
|
public ngIf: any = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function assertTemplate(property: string, templateRef: TemplateRef<any>): void {
|
||||||
|
const isTemplateRef = templateRef.createEmbeddedView != null;
|
||||||
|
if (!isTemplateRef) {
|
||||||
|
throw new Error(`${property} must be a TemplateRef, but received '${stringify(templateRef)}'.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -217,6 +217,28 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
|
||||||
expect(fixture.nativeElement).toHaveText('false');
|
expect(fixture.nativeElement).toHaveText('false');
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('Type guarding', () => {
|
||||||
|
it('should throw when then block is not template', async(() => {
|
||||||
|
const template = '<span *ngIf="booleanCondition; then thenBlock">IGNORE</span>' +
|
||||||
|
'<div #thenBlock>THEN</div>';
|
||||||
|
|
||||||
|
fixture = createTestComponent(template);
|
||||||
|
|
||||||
|
expect(() => fixture.detectChanges())
|
||||||
|
.toThrowError(/ngIfThen must be a TemplateRef, but received/);
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should throw when else block is not template', async(() => {
|
||||||
|
const template = '<span *ngIf="booleanCondition; else elseBlock">IGNORE</span>' +
|
||||||
|
'<div #elseBlock>ELSE</div>';
|
||||||
|
|
||||||
|
fixture = createTestComponent(template);
|
||||||
|
|
||||||
|
expect(() => fixture.detectChanges())
|
||||||
|
.toThrowError(/ngIfElse must be a TemplateRef, but received/);
|
||||||
|
}));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue