Skip to content
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

PanelMenu#model does not support immutable objects (signalState) #17506

Open
1 of 4 tasks
robmanganelly opened this issue Jan 27, 2025 · 0 comments
Open
1 of 4 tasks

PanelMenu#model does not support immutable objects (signalState) #17506

robmanganelly opened this issue Jan 27, 2025 · 0 comments
Labels
Status: Needs Triage Issue will be reviewed by Core Team and a relevant label will be added as soon as possible

Comments

@robmanganelly
Copy link

Describe the bug

PanelMenu#model requires an array of MenuItem elements, but if this array is coming from an immutable source (signalState) the component will not update the state on user interactions, and it will try to mutate the object, which causes a TypeError

Image

I forked the repo, but at the moment can't submit a PR, I sincerely apologize. I will revisit this issue later and will contribute if it is still open.

Hacky Patch

This should be a temporary patch for consumers that are required to use immutable objects

If you cannot change the component and are required to use reactive state, or any other immutable object, you can use this patch

// excerpt from Myservice.ts
private state = signalState<TState>({
    //...other props
    menu: navItems, // default value
  });

  readonly opened = this.state.opened;

  // readonly menu = this.state.menu; // replace to this once the bug is fixed
  get menu() {
    return JSON.parse(JSON.stringify(this.state.menu()));
  }
  set menu(menu: TState['menu']) {
    patchState(this.state, { menu });
  }

then in the component

export class MyComponent {

  #nav = inject(MyService);

  readonly menu = this.#nav.menu;  //MenuItem[]

  //...rest of the code
}

Why
signalState objects have been frozen recursively, so the only "easy" way to defrost them is to create a new object. Spread operator create shallow copies (won't work)

Important
do not create that getter/setter in the component because signals trigger change detection cycles and that would cause an infinite loop. This is expected to happen in the data layer.

Pull Request Link

No response

Reason for not contributing a PR

  • Lack of time
  • Unsure how to implement the fix/feature
  • Difficulty understanding the codebase
  • Other

Other Reason

No response

Reproducer

https://stackblitz.com/edit/github-tamhkczt

Environment

nx workspace +
angular19 + ngrx/signals@19

Angular version

19.x.x

PrimeNG version

v19

Node version

22.x.x

Browser(s)

Chrome

Steps to reproduce the behavior

  1. Open the console
  2. Click any menu option
  3. you should see an error in console TypeError
  4. menu won't open

Expected behavior

When the user clicks the options, the menu should open if it has children

@robmanganelly robmanganelly added the Status: Needs Triage Issue will be reviewed by Core Team and a relevant label will be added as soon as possible label Jan 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Needs Triage Issue will be reviewed by Core Team and a relevant label will be added as soon as possible
Projects
None yet
Development

No branches or pull requests

1 participant