Skip to content

Commit 76790a6

Browse files
cexbrayatPawel Kozlowski
authored andcommitted
fix(core): improve the missing control flow directive message (#46903)
Similarly to what has been done in #46846 for the extended diagnostics about missing control flow directive that was only mentioning that the `CommonModule` should be imported, this commit improves the validation done by the JiT compiler. Now that the control flow directives are available as standalone, the message mentions that directive itself can be imported. The message now also mentions which import should be used for the directive (as it can be tricky to figure out that `NgForOf` is the directive corresponding to `*ngFor`). PR Close #46903
1 parent d583f85 commit 76790a6

2 files changed

Lines changed: 14 additions & 9 deletions

File tree

packages/core/src/render3/instructions/element_validation.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -187,9 +187,11 @@ export function handleUnknownPropertyError(
187187
'a part of an @NgModule where this component is declared';
188188
if (KNOWN_CONTROL_FLOW_DIRECTIVES.has(propName)) {
189189
// Most likely this is a control flow directive (such as `*ngIf`) used in
190-
// a template, but the `CommonModule` is not imported.
190+
// a template, but the directive or the `CommonModule` is not imported.
191+
const correspondingImport = KNOWN_CONTROL_FLOW_DIRECTIVES.get(propName);
191192
message += `\nIf the '${propName}' is an Angular control flow directive, ` +
192-
`please make sure that the 'CommonModule' is ${importLocation}.`;
193+
`please make sure that either the '${
194+
correspondingImport}' directive or the 'CommonModule' is ${importLocation}.`;
193195
} else {
194196
// May be an Angular component, which is not imported/declared?
195197
message += `\n1. If '${tagName}' is an Angular component and it has the ` +
@@ -275,13 +277,14 @@ function getTemplateLocationDetails(lView: LView): string {
275277
}
276278

277279
/**
278-
* The set of known control flow directives.
280+
* The set of known control flow directives and their corresponding imports.
279281
* We use this set to produce a more precises error message with a note
280282
* that the `CommonModule` should also be included.
281283
*/
282-
export const KNOWN_CONTROL_FLOW_DIRECTIVES =
283-
new Set(['ngIf', 'ngFor', 'ngSwitch', 'ngSwitchCase', 'ngSwitchDefault']);
284-
284+
export const KNOWN_CONTROL_FLOW_DIRECTIVES = new Map([
285+
['ngIf', 'NgIf'], ['ngFor', 'NgForOf'], ['ngSwitchCase', 'NgSwitchCase'],
286+
['ngSwitchDefault', 'NgSwitchDefault']
287+
]);
285288
/**
286289
* Returns true if the tag name is allowed by specified schemas.
287290
* @param schemas Array of schemas

packages/core/test/acceptance/ng_module_spec.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -634,7 +634,7 @@ describe('NgModule', () => {
634634
lines.forEach(line => expect(errorMessage).toMatch(line));
635635
});
636636

637-
KNOWN_CONTROL_FLOW_DIRECTIVES.forEach(directive => {
637+
KNOWN_CONTROL_FLOW_DIRECTIVES.forEach((correspondingImport, directive) => {
638638
it(`should produce a warning when the '${directive}' directive ` +
639639
`is used in a template, but not imported in corresponding NgModule`,
640640
() => {
@@ -663,7 +663,8 @@ describe('NgModule', () => {
663663
`NG0303: Can't bind to '${
664664
directive}' since it isn't a known property of 'div' \\(used in the 'App' component template\\).`,
665665
`If the '${directive}' is an Angular control flow directive, please make sure ` +
666-
`that the 'CommonModule' is a part of an @NgModule where this component is declared.`
666+
`that either the '${
667+
correspondingImport}' directive or the 'CommonModule' is a part of an @NgModule where this component is declared.`
667668
];
668669
lines.forEach(line => expect(errorMessage).toMatch(line));
669670
});
@@ -690,7 +691,8 @@ describe('NgModule', () => {
690691
`NG0303: Can't bind to '${
691692
directive}' since it isn't a known property of 'div' \\(used in the 'App' component template\\).`,
692693
`If the '${directive}' is an Angular control flow directive, please make sure ` +
693-
`that the 'CommonModule' is included in the '@Component.imports' of this component.`
694+
`that either the '${
695+
correspondingImport}' directive or the 'CommonModule' is included in the '@Component.imports' of this component.`
694696
];
695697
lines.forEach(line => expect(errorMessage).toMatch(line));
696698
});

0 commit comments

Comments
 (0)