primefaces / primeng

The Most Complete Angular UI Component Library
https://primeng.org
Other
10.29k stars 4.56k forks source link

p-multiselect: Reactive forms setValue updates the underlying model but does not show new changes in dropdown. #15765

Open nickyg91 opened 4 months ago

nickyg91 commented 4 months ago

Describe the bug

When subscribing to valueChanges on a reactive form control and subsequently calling setValue on that same reactive form control the underlying data changes but the dropdown does not update with the newly selected items.

Environment

Reproducer

https://stackblitz.com/edit/github-tynx23?file=src%2Fapp%2Fapp.component.html,src%2Fapp%2Fapp.component.ts,src%2Fapp%2Fapp.module.ts

Angular version

17.3.10

PrimeNG version

17.18

Build / Runtime

Angular CLI App

Language

TypeScript

Node version (for AoT issues node --version)

20.11.1

Browser(s)

Edge 125.0.2535.67

Steps to reproduce the behavior

  1. Open first primeng multiselect
  2. Select Apple and Pear
  3. Select Banana
  4. See the underlying data change to ["Banana"] but the Multiselect Dropdown Shows Apple, Banana, and Pear selected.

Expected behavior

  1. Open first primeng multiselect
  2. Select Apple and Pear
  3. Select Banana
  4. Multiselect should only have Banana checked.
pavankjadda commented 4 months ago

@nickyg91 when you call set on same control, you are essentially overwriting it. Hence the bug. Run my updated example and see log statements.

To fix it, just remove ngAfterViewInit(). BTW, what are you trying to achieve here?

nickyg91 commented 4 months ago

The example here is very pared down to what we are actually trying to do, but basically our use case is the following:

If a user selects a certain value in the multi select the other selected values should be deselected. The negative case would apply here as well but is not illustrated for brevity - if Banana were selected and then the user checked Apple - Banana would be deselected. In the actual use case the subscription is happening in a constructor and is not working.

This had been working in previous versions but the case this is used in is pretty rare and got missed during one of our regressions and escaped into production. We want the old values overwritten with the new value - the example I provided also has a template form version that works exactly as it should.

The underlying form control has the correct value, but the dropdown does not mirror what the form control has as the current value in this case.

I did try your suggested fix and that did not resolve the issue. I must have linked an out of date version of the stack blitz as I had the subscription in the ngOnInit.

pavankjadda commented 4 months ago

The example here is very pared down to what we are actually trying to do, but basically our use case is the following:

If a user selects a certain value in the multi select the other selected values should be deselected. The negative case would apply here as well but is not illustrated for brevity - if Banana were selected and then the user checked Apple - Banana would be deselected. In the actual use case the subscription is happening in a constructor and is not working.

This had been working in previous versions but the case this is used in is pretty rare and got missed during one of our regressions and escaped into production. We want the old values overwritten with the new value - the example I provided also has a template form version that works exactly as it should.

The underlying form control has the correct value, but the dropdown does not mirror what the form control has as the current value in this case.

I did try your suggested fix and that did not resolve the issue. I must have linked an out of date version of the stack blitz as I had the subscription in the ngOnInit.

This peculiar and looks like good use case for dropdown

nickyg91 commented 4 months ago

The example here is very pared down to what we are actually trying to do, but basically our use case is the following:

If a user selects a certain value in the multi select the other selected values should be deselected. The negative case would apply here as well but is not illustrated for brevity - if Banana were selected and then the user checked Apple - Banana would be deselected. In the actual use case the subscription is happening in a constructor and is not working.

This had been working in previous versions but the case this is used in is pretty rare and got missed during one of our regressions and escaped into production. We want the old values overwritten with the new value - the example I provided also has a template form version that works exactly as it should.

The underlying form control has the correct value, but the dropdown does not mirror what the form control has as the current value in this case.

I did try your suggested fix and that did not resolve the issue. I must have linked an out of date version of the stack blitz as I had the subscription in the ngOnInit.

This peculiar and looks like good use case for dropdown

A dropdown does not allow a user to select multiple values therefore it does not satisfy our use case.

Given the stack blitz - a user should be able to select Apple and Pear, but if Banana is selected the others should deselect.

pavankjadda commented 4 months ago

The example here is very pared down to what we are actually trying to do, but basically our use case is the following: If a user selects a certain value in the multi select the other selected values should be deselected. The negative case would apply here as well but is not illustrated for brevity - if Banana were selected and then the user checked Apple - Banana would be deselected. In the actual use case the subscription is happening in a constructor and is not working. This had been working in previous versions but the case this is used in is pretty rare and got missed during one of our regressions and escaped into production. We want the old values overwritten with the new value - the example I provided also has a template form version that works exactly as it should. The underlying form control has the correct value, but the dropdown does not mirror what the form control has as the current value in this case. I did try your suggested fix and that did not resolve the issue. I must have linked an out of date version of the stack blitz as I had the subscription in the ngOnInit.

This peculiar and looks like good use case for dropdown

A dropdown does not allow a user to select multiple values therefore it does not satisfy our use case.

Given the stack blitz - a user should be able to select Apple and Pear, but if Banana is selected the others should deselect.

I get it now. Not sure if this is in the scope of the project

nickyg91 commented 4 months ago

The example here is very pared down to what we are actually trying to do, but basically our use case is the following: If a user selects a certain value in the multi select the other selected values should be deselected. The negative case would apply here as well but is not illustrated for brevity - if Banana were selected and then the user checked Apple - Banana would be deselected. In the actual use case the subscription is happening in a constructor and is not working. This had been working in previous versions but the case this is used in is pretty rare and got missed during one of our regressions and escaped into production. We want the old values overwritten with the new value - the example I provided also has a template form version that works exactly as it should. The underlying form control has the correct value, but the dropdown does not mirror what the form control has as the current value in this case. I did try your suggested fix and that did not resolve the issue. I must have linked an out of date version of the stack blitz as I had the subscription in the ngOnInit.

This peculiar and looks like good use case for dropdown

A dropdown does not allow a user to select multiple values therefore it does not satisfy our use case.

Given the stack blitz - a user should be able to select Apple and Pear, but if Banana is selected the others should deselect.

I get it now. Not sure if this is in the scope of the project

This had been working in primeng v16. We recently upgraded to v17 and Angular v17 which is how this issue cropped up.