Skip to content

Commit

Permalink
fix(core): handle if alias in control flow migration (#52181)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
cexbrayat authored and pkozlowski-opensource committed Oct 16, 2023
1 parent eaf735d commit e5720ed
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 3 deletions.
Expand Up @@ -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) + `}`;
Expand All @@ -266,7 +268,8 @@ function buildIfBlock(
function buildIfElseBlock(
etm: ElementToMigrate, ngTemplates: Map<string, Template>, 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}) {`;
Expand All @@ -291,7 +294,7 @@ function buildIfElseBlock(
function buildIfThenElseBlock(
etm: ElementToMigrate, ngTemplates: Map<string, Template>, 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 {`;
Expand Down
84 changes: 84 additions & 0 deletions packages/core/schematics/test/control_flow_migration_spec.ts
Expand Up @@ -363,6 +363,90 @@ describe('control flow migration', () => {
`<ng-container *ngTemplateOutlet="blockUsedElsewhere"></ng-container>`,
].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', [`<div *ngIf="user$ | async as user">{{ user.name }}</div>`].join('\n'));

await runMigration();
const content = tree.readContent('/comp.html');

expect(content).toBe(
[`@if (user$ | async; as user) {<div>{{ user.name }}</div>}`].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', [
`<div>`,
`<div *ngIf="user$ | async as user; else noUserBlock">{{ user.name }}</div>`,
`<ng-template #noUserBlock>No user</ng-template>`,
`</div>`,
].join('\n'));

await runMigration();
const content = tree.readContent('/comp.html');

expect(content).toBe([
`<div>`,
`@if (user$ | async; as user) {<div>{{ user.name }}</div>} @else {No user}`,
`</div>`,
].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', [
`<div>`,
`<ng-container *ngIf="user$ | async as user; then userBlock; else noUserBlock">Ignored</ng-container>`,
`<ng-template #userBlock>User</ng-template>`,
`<ng-template #noUserBlock>No user</ng-template>`,
`</div>`,
].join('\n'));

await runMigration();
const content = tree.readContent('/comp.html');

expect(content).toBe([
`<div>`,
`@if (user$ | async; as user) {User} @else {No user}`,
`</div>`,
].join('\n'));
});
});

describe('ngFor', () => {
Expand Down

0 comments on commit e5720ed

Please sign in to comment.