Skip to content

feat(eslint-plugin-template): add rule prefer-at-empty #2352

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

reduckted
Copy link
Contributor

Closes #2350

New rule @angular-eslint/template/prefer-at-empty will find code in templates where the @empty block of a @for block could be used instead of using an @if block.

For example, it will find this:

@for (item of items; track $index) {
    {{ item }}
}
@if (items.length === 0) {
  No items
}

and change it to this:

@for (item of items; track $index) {
    {{ item }}
} @empty {
  No items
}

I originally wrote this to just report the problems and not provide a fix, however because there are a few different scenarios that it detects, it wasn't always obvious how to fix the problem. I considered using the message to explain what needs to change, but then I figured if it's going to explain what needs to be changed, why not just change it!

The fixes change the code enough to make the problem go away, but it doesn't do any formatting, so the expected output in the tests can look a bit messy, but a formatter like Prettier will fix that up nicely.

There are six different scenarios that can be detected. Of course, in each scenario, the collection used in the for block must be the same collection used in the @if blocks. The scenarios are:

  1. @for followed by an "is empty" @if:
@for (item of items; track $index) {
}
@if (items.length === 0) {
}
  1. An "is empty" @if followed by @for:
@if (items.length === 0) {
}
@for (item of items; track $index) {
}
  1. An "is not empty" @if with an @else, where the @if branch contains a @for:
@if (items.length > 0) {
    @for (item of items; track $index) {
    }
} @else {
}
  1. An "is empty" @if with an @else, where the @else branch contains a @for:
@if (items.length === 0) {
} @else { 
    @for (item of items; track $index) {
    }
}
  1. An "is not empty" @if with a @for, followed by an "is empty" @if:
@if (items.length > 0) {
    @for (item of items; track $index) {
    }
}
@if (items.length === 0) {
}
  1. An "is empty" @if followed by an "is not empty" @if with a @for:
@if (items.length === 0) {
}
@if (items.length > 0) {
    @for (item of items; track $index) {
    }
}

Copy link

nx-cloud bot commented Apr 8, 2025

View your CI Pipeline Execution ↗ for commit 811c417.

Command Status Duration Result
nx run-many -t e2e-suite --parallel 1 ✅ Succeeded 33s View ↗
nx run-many -t test --codeCoverage ✅ Succeeded 1m 9s View ↗
nx run-many -t build,typecheck,check-rule-docs,... ✅ Succeeded 1m 32s View ↗
nx-cloud record -- pnpm nx sync:check ✅ Succeeded 4s View ↗
nx-cloud record -- pnpm format-check ✅ Succeeded 5s View ↗
nx run-many -t test ✅ Succeeded 29s View ↗
nx run-many -t build ✅ Succeeded 15s View ↗

☁️ Nx Cloud last updated this comment at 2025-04-08 10:26:27 UTC

Copy link

codecov bot commented Apr 8, 2025

Codecov Report

Attention: Patch coverage is 94.90446% with 8 lines in your changes missing coverage. Please review.

Project coverage is 92.63%. Comparing base (0bda61b) to head (811c417).

Files with missing lines Patch % Lines
...slint-plugin-template/src/rules/prefer-at-empty.ts 94.59% 4 Missing and 4 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2352      +/-   ##
==========================================
+ Coverage   92.53%   92.63%   +0.09%     
==========================================
  Files         184      186       +2     
  Lines        3726     3883     +157     
  Branches      836      899      +63     
==========================================
+ Hits         3448     3597     +149     
- Misses        215      219       +4     
- Partials       63       67       +4     
Flag Coverage Δ
unittest 92.63% <94.90%> (+0.09%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
packages/eslint-plugin-template/src/index.ts 100.00% <100.00%> (ø)
...ugin-template/tests/rules/prefer-at-empty/cases.ts 100.00% <100.00%> (ø)
...slint-plugin-template/src/rules/prefer-at-empty.ts 94.59% <94.59%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@rubiesonthesky
Copy link
Contributor

Could the description be expanded little bit to say why you should enable this lint rule or why you should be using @empty instead of the other code? This rule is maybe easier to understand, but I have just been trying to read through all the rules, and some of them it's not very clear what they do and why. Or maybe it could be good practice to link the original issue or PR in the description? For example, this PR shows the examples in a lot readable way than the generated rule markdown. :)

For this rule, the "why" could be just simple "Prefer using @empty with @for loops instead of a separate @if or @else block, to make code shorter and easier to read." - It would indicate that this is stylistic thing and not really a problem or bug in a code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants