Skip to content

Commit f1d1f16

Browse files
authored
Merge pull request #3073 from koenvd/combobox_value_safety_in_multi_select
Properly handle null in writeValue when in multiselect mode and itemValueKey is defined
2 parents cd447b6 + 1a4b698 commit f1d1f16

File tree

2 files changed

+33
-8
lines changed

2 files changed

+33
-8
lines changed

src/combobox/combobox.component.spec.ts

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,20 @@ import { PlaceholderModule } from "./../placeholder/index";
2121
placeholder="placeholder"
2222
label="label"
2323
[items]="items"
24-
[(ngModel)]="model">
24+
[(ngModel)]="model"
25+
[type]="type"
26+
[itemValueKey]="itemValueKey">
2527
<cds-dropdown-list></cds-dropdown-list>
2628
</cds-combo-box>`
2729
})
2830
class ComboboxTest {
2931
items = [
30-
{content: "one", selected: false},
31-
{content: "two", selected: false},
32-
{content: "three", selected: false}
32+
{id: "1", content: "one", selected: false},
33+
{id: "2", content: "two", selected: false},
34+
{id: "3", content: "three", selected: false}
3335
];
36+
type = 'single';
37+
itemValueKey = undefined;
3438
model: ListItem;
3539
}
3640

@@ -76,6 +80,7 @@ describe("Combo box", () => {
7680
fixture.detectChanges();
7781

7882
expect(element.nativeElement.querySelector("input").value).toBe("one");
83+
expect(wrapper.model.id).toBe("1");
7984
expect(wrapper.model.content).toBe("one");
8085
expect(wrapper.model.selected).toBe(true);
8186

@@ -173,9 +178,9 @@ describe("Combo box", () => {
173178
textInput.dispatchEvent(new Event("input"));
174179

175180
wrapper.items = [
176-
{content: "four", selected: false},
177-
{content: "five", selected: false},
178-
{content: "six", selected: false}
181+
{id: "4", content: "four", selected: false},
182+
{id: "5", content: "five", selected: false},
183+
{id: "6", content: "six", selected: false}
179184
];
180185

181186
fixture.detectChanges();
@@ -184,4 +189,24 @@ describe("Combo box", () => {
184189

185190
expect(itemEls.length).toEqual(2);
186191
});
192+
193+
it("should update model by itemValueKey when specified", () => {
194+
fixture = TestBed.createComponent(ComboboxTest);
195+
wrapper = fixture.componentInstance;
196+
wrapper.type = "multi";
197+
wrapper.itemValueKey = "id";
198+
fixture.detectChanges();
199+
200+
element = fixture.debugElement.query(By.css("cds-combo-box"));
201+
202+
const dropdownToggle = element.nativeElement.querySelector(".cds--list-box__field");
203+
dropdownToggle.click();
204+
fixture.detectChanges();
205+
206+
const dropdownOption = element.nativeElement.querySelector(".cds--list-box__menu-item");
207+
dropdownOption.click();
208+
fixture.detectChanges();
209+
210+
expect(wrapper.model).toEqual(['1']);
211+
});
187212
});

src/combobox/combobox.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -638,7 +638,7 @@ export class ComboBox implements OnChanges, AfterViewInit, AfterContentInit, OnD
638638
// clone the items and update their state based on the received value array
639639
// this way we don't lose any additional metadata that may be passed in via the `items` Input
640640
let newValues = [];
641-
for (const v of value) {
641+
for (const v of value ?? []) {
642642
for (const item of this.view.getListItems()) {
643643
if (item[this.itemValueKey] === v) {
644644
newValues.push(Object.assign({}, item, { selected: true }));

0 commit comments

Comments
 (0)