Skip to content

Conversation

@wartab
Copy link
Contributor

@wartab wartab commented Nov 11, 2024

Currently, the @switch/@case syntax is fairly limited, as cases may only have one guard. This often requires to either copy paste the body of the case-block or to refactor code to use @if / @else if syntax instead. This adds support for the highly requested feature of being able to define multiple guards to a single @case using the syntax @case(a; b; c)

PR Checklist

Please check if your PR fulfills the following requirements:

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Documentation content changes
  • angular.dev application / infrastructure changes
  • Other... Please describe:

What is the current behavior?

You can't have multiple conditions in a single case block.

Issue Number: #14659

What is the new behavior?

Now you can

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

I'm not certain if other tests are needed.

I made a few tests building this locally and this all works:

@Component({
  selector: 'app-root',
  standalone: true,
  template: `@switch (myVar) {
  @case (1; 2) {
    <div>{{myVar}}</div>
  }

  @default {
    <div>Default {{myVar}}</div>
  }
}
`,
  styleUrl: './app.component.scss'
})
export class AppComponent {
  myVar: number = 2; // replace by whatever you want

  public addOne() {
    this.myVar++;
  }
}

This does accurately not compile:

@Component({
  selector: 'app-root',
  standalone: true,
  template: `@switch (myVar) {
    @case (1) {
      <div>{{myVar}}</div>
    }

    @case (2; 3) {
      <div>{{myVar}}</div>
    }

    @default {
      <div>Default {{myVar}}</div>
    }
}
`,
  styleUrl: './app.component.scss'
})
export class AppComponent {
  myVar: 1 | 2 = 1;

  public addOne() {
    this.myVar++;
  }
}


Application bundle generation failed. [0.065 seconds]

X [ERROR] NG8: Type '3' is not comparable to type '1 | 2'. [plugin angular-compiler]

    src/app/app.component.ts:11:14:
      11 │     @case (2; 3) {
         ╵               ^



@angular-robot angular-robot bot added detected: feature PR contains a feature commit area: compiler Issues related to `ngc`, Angular's template compiler labels Nov 11, 2024
@ngbot ngbot bot added this to the Backlog milestone Nov 11, 2024
…ch control flow

Currently, the @switch/@case syntax is fairly limited, as cases may only have one guard. This often requires to either copy paste the body of the case-block or to refactor code to use @if / @else if syntax instead. This adds support for the highly requested feature of being able to define multiple guards to a single @case using the syntax @case(a; b; c)
@wartab wartab force-pushed the multiple-switch-cases branch from c66b7d4 to 7954fb8 Compare November 11, 2024 21:33
@angular-robot angular-robot bot added area: compiler Issues related to `ngc`, Angular's template compiler and removed area: compiler Issues related to `ngc`, Angular's template compiler labels Nov 11, 2024
@wartab
Copy link
Contributor Author

wartab commented Nov 11, 2024

Also, I tried to implement the following syntax:

@case(1)
@case(2) {
...
}

But that was just way too difficult to do, as the BlockStart structure just wasn't flexible enough to allow for it easily. Nonetheless, I'll give it a try if it's preferred.

@JeanMeche
Copy link
Member

I see at least 2 types of tests that we would need to add.

  • Compliance tests in packages/compiler-cli/test/compliance/test_cases/, those tests ensure we don't introduce regressions on the compiler output.
  • runtime tests in packages/core/test/render3/

Copy link
Member

@josephperrott josephperrott left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Reviewed-for: dev-infra

@alxhub alxhub self-assigned this Nov 14, 2024
@angular-robot angular-robot bot added area: compiler Issues related to `ngc`, Angular's template compiler and removed area: compiler Issues related to `ngc`, Angular's template compiler labels Nov 18, 2024
@ngbot ngbot bot modified the milestone: Backlog Nov 18, 2024
@wartab
Copy link
Contributor Author

wartab commented Nov 18, 2024

Took me a while to understand how the compiler tests work, but I did add a compliance test. I couldn't really think of anything that isn't already covered with other tests, but please hint me in the right direction if you think there need to be more tests.

That said, when it comes to runtime tests, I tried to find examples where you cited them, but I couldn't find any control flow related tests there.
Tests there seem to be testing more higher level things in the framework itself. I'm not opposed to adding tests, but given I'm not very experienced with the compiler when it comes to Angular internals, I feel more confident when I can base my work on already exisitng examples.

@wartab
Copy link
Contributor Author

wartab commented Nov 18, 2024

Also on a side note, I'm pretty impressed that the minimizer can optimise ternary expressions so well,

The a === 0 ? .... : a=== 2 chain actually gets optimised to a===0||a===1||a===2

I think one step could be to actually generate switch/case expressions, but that - again :( - seems to be a whole different beast for me.

@thePunderWoman thePunderWoman marked this pull request as draft May 21, 2025 15:30
@wartab
Copy link
Contributor Author

wartab commented May 28, 2025

I just noticed that this PR got marked as draft. I assume it's because of the merge conflicts with main.

I know that this PR was not solicitted by the Angular team, so I'm not sure if there's any chance this PR gets accepted if I update the PR to be compatible with the current main branch. Could you please let me know if I should try to update the PR or just drop it?

@thePunderWoman
Copy link
Contributor

@wartab We went through and marked all old PRs that haven't moved to draft. If you'd like to see this move forward though, please update and get it to a fresh reviewable state and we'll revisit.

@wartab
Copy link
Contributor Author

wartab commented Jun 3, 2025

Given this isn't a trivial change, I'd just like to know if spending time on this even makes sense. I want this feature to be added, I want to help to make it happen, but for that I'd also like to know if there's a chance this will be accepted if I re-implement the feature and the tests. I say this because I didn't get a response to my question regarding tests and so the PR just ended up being in conflict over time.

@thePunderWoman
Copy link
Contributor

@wartab There was a conversation about this and the answer was that we do want this feature, but I think there were concerns about this implementation. So with that, it's probably best to close this for now. I know @alxhub has more thoughts here and I'll leave it to him to provide his thoughts. Thank you though! It's a great feature and we appreciate you for your effort.

@wartab
Copy link
Contributor Author

wartab commented Jun 4, 2025

@thePunderWoman Thank you for your honesty. Just fyi, when you changed the PRs to drafts, I didn't get a notification, so people might miss that it happened.

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Jul 5, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area: compiler Issues related to `ngc`, Angular's template compiler detected: feature PR contains a feature commit

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants