From e5720edb460a1bb51475c78d3bd442da52991a46 Mon Sep 17 00:00:00 2001 From: cexbrayat Date: Thu, 12 Oct 2023 14:48:22 +0200 Subject: [PATCH] fix(core): handle if alias in control flow migration (#52181) This adds the support of `if ` conditions with `as` clause when migrating to the control flow syntax. It now adds the required semicolon before the `as` when migrating the template. Before: `@if (user$ | async as user) {` After: `@if (user$ | async; as user) {` PR Close #52181 --- .../control-flow-migration/util.ts | 9 +- .../test/control_flow_migration_spec.ts | 84 +++++++++++++++++++ 2 files changed, 90 insertions(+), 3 deletions(-) diff --git a/packages/core/schematics/ng-generate/control-flow-migration/util.ts b/packages/core/schematics/ng-generate/control-flow-migration/util.ts index ee41df9331365..9353ae74e150a 100644 --- a/packages/core/schematics/ng-generate/control-flow-migration/util.ts +++ b/packages/core/schematics/ng-generate/control-flow-migration/util.ts @@ -252,7 +252,9 @@ function migrateNgIf( function buildIfBlock( etm: ElementToMigrate, tmpl: string, offset: number): {tmpl: string, offset: number} { - const condition = etm.attr.value; + // includes the mandatory semicolon before as + const condition = etm.attr.value.replace(' as ', '; as '); + const startBlock = `@if (${condition}) {`; const ifBlock = startBlock + getMainBlock(etm, tmpl, offset) + `}`; @@ -266,7 +268,8 @@ function buildIfBlock( function buildIfElseBlock( etm: ElementToMigrate, ngTemplates: Map, tmpl: string, elseString: string, offset: number): {tmpl: string, offset: number} { - const condition = etm.getCondition(elseString); + // includes the mandatory semicolon before as + const condition = etm.getCondition(elseString).replace(' as ', '; as '); const elseTmpl = ngTemplates.get(`#${etm.getTemplateName(elseString)}`)!; const startBlock = `@if (${condition}) {`; @@ -291,7 +294,7 @@ function buildIfElseBlock( function buildIfThenElseBlock( etm: ElementToMigrate, ngTemplates: Map, tmpl: string, thenString: string, elseString: string, offset: number): {tmpl: string, offset: number} { - const condition = etm.getCondition(thenString); + const condition = etm.getCondition(thenString).replace(' as ', '; as '); const startBlock = `@if (${condition}) {`; const elseBlock = `} @else {`; diff --git a/packages/core/schematics/test/control_flow_migration_spec.ts b/packages/core/schematics/test/control_flow_migration_spec.ts index c473786e2728d..4e42c396f0c98 100644 --- a/packages/core/schematics/test/control_flow_migration_spec.ts +++ b/packages/core/schematics/test/control_flow_migration_spec.ts @@ -363,6 +363,90 @@ describe('control flow migration', () => { ``, ].join('\n')); }); + + it('should migrate if with alias', async () => { + writeFile('/comp.ts', ` + import {Component} from '@angular/core'; + import {NgIf} from '@angular/common'; + + @Component({ + templateUrl: './comp.html' + }) + class Comp { + user$ = of({ name: 'Jane' }}) + } + `); + + writeFile( + '/comp.html', [`
{{ user.name }}
`].join('\n')); + + await runMigration(); + const content = tree.readContent('/comp.html'); + + expect(content).toBe( + [`@if (user$ | async; as user) {
{{ user.name }}
}`].join('\n')); + }); + + it('should migrate if/else with alias', async () => { + writeFile('/comp.ts', ` + import {Component} from '@angular/core'; + import {NgIf} from '@angular/common'; + + @Component({ + templateUrl: './comp.html' + }) + class Comp { + user$ = of({ name: 'Jane' }}) + } + `); + + writeFile('/comp.html', [ + `
`, + `
{{ user.name }}
`, + `No user`, + `
`, + ].join('\n')); + + await runMigration(); + const content = tree.readContent('/comp.html'); + + expect(content).toBe([ + `
`, + `@if (user$ | async; as user) {
{{ user.name }}
} @else {No user}`, + `
`, + ].join('\n')); + }); + + it('should migrate if/then/else with alias', async () => { + writeFile('/comp.ts', ` + import {Component} from '@angular/core'; + import {NgIf} from '@angular/common'; + + @Component({ + templateUrl: './comp.html' + }) + class Comp { + user$ = of({ name: 'Jane' }}) + } + `); + + writeFile('/comp.html', [ + `
`, + `Ignored`, + `User`, + `No user`, + `
`, + ].join('\n')); + + await runMigration(); + const content = tree.readContent('/comp.html'); + + expect(content).toBe([ + `
`, + `@if (user$ | async; as user) {User} @else {No user}`, + `
`, + ].join('\n')); + }); }); describe('ngFor', () => {