Skip to content

Commit

Permalink
fix(core): handle for alias with as in control flow migration (#52183)
Browse files Browse the repository at this point in the history
This adds the support of `let index as myIndex` in `*ngFor` for the control flow migration.

Before: `@for (itm of items; track itm)`
After: `@for (itm of items; track itm; let myIndex = $index)`

PR Close #52183
  • Loading branch information
cexbrayat authored and pkozlowski-opensource committed Oct 12, 2023
1 parent 0792424 commit ffe9b1f
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 2 deletions.
Expand Up @@ -169,7 +169,8 @@ export function migrateTemplate(template: string): string|null {

function migrateNgFor(
etm: ElementToMigrate, tmpl: string, offset: number): {tmpl: string, offset: number} {
const aliasRegexp = /=\s+(count|index|first|last|even|odd)/gm;
const aliasWithEqualRegexp = /=\s+(count|index|first|last|even|odd)/gm;
const aliasWithAsRegexp = /(count|index|first|last|even|odd)\s+as/gm;
const aliases = [];

const parts = etm.attr.value.split(';');
Expand All @@ -187,10 +188,20 @@ function migrateNgFor(
trackBy = `${trackByFn}($index, ${loopVar})`;
}
// aliases
if (part.match(aliasRegexp)) {
// declared with `let myIndex = index`
if (part.match(aliasWithEqualRegexp)) {
// 'let myIndex = index' -> ['let myIndex', 'index']
const aliasParts = part.split('=');
// -> 'let myIndex = $index'
aliases.push(` ${aliasParts[0].trim()} = $${aliasParts[1].trim()}`);
}
// declared with `index as myIndex`
if (part.match(aliasWithAsRegexp)) {
// 'index as myIndex' -> ['index', 'myIndex']
const aliasParts = part.split(/\s+as\s+/);
// -> 'let myIndex = $index'
aliases.push(` let ${aliasParts[1].trim()} = $${aliasParts[0].trim()}`);
}
}

const aliasStr = (aliases.length > 0) ? `;${aliases.join(';')}` : '';
Expand Down
25 changes: 25 additions & 0 deletions packages/core/schematics/test/control_flow_migration_spec.ts
Expand Up @@ -521,6 +521,31 @@ describe('control flow migration', () => {
'template: `<ul>@for (itm of items; track itm; let index = $index) {<li>{{itm.text}}</li>}</ul>`');
});

it('should migrate with alias declared with as', async () => {
writeFile('/comp.ts', `
import {Component} from '@angular/core';
import {NgFor} from '@angular/common';
interface Item {
id: number;
text: string;
}
@Component({
imports: [NgFor],
template: \`<ul><li *ngFor="let itm of items; index as myIndex">{{itm.text}}</li></ul>\`
})
class Comp {
items: Item[] = [{id: 1, text: 'blah'},{id: 2, text: 'stuff'}];
}
`);

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

expect(content).toContain(
'template: `<ul>@for (itm of items; track itm; let myIndex = $index) {<li>{{itm.text}}</li>}</ul>`');
});

it('should migrate with multiple aliases', async () => {
writeFile('/comp.ts', `
import {Component} from '@angular/core';
Expand Down

0 comments on commit ffe9b1f

Please sign in to comment.