@ng-select/ng-select 21.5.0 → 21.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -18,6 +18,7 @@ See [Demo](https://ng-select.github.io/ng-select) page.
18
18
 
19
19
  | Angular | ng-select |
20
20
  |------------------|:------------------:|
21
+ | >=22.0.0 <23.0.0 | v22.x.x |
21
22
  | >=21.0.0 <22.0.0 | v21.x.x |
22
23
  | >=20.0.0 <21.0.0 | <=15.1.3, >=20.0.1 |
23
24
  | >=19.0.0 <20.0.0 | v14.x |
@@ -270,7 +271,7 @@ map: {
270
271
  | (search) | Fired while typing search term. Outputs search term with filtered items |
271
272
  | (open) | Fired on select dropdown open |
272
273
  | (remove) | Fired when item is removed while `[multiple]="true"` |
273
- | (scroll) | Fired when scrolled. Provides the start and end index of the currently available items. Can be used for loading more items in chunks before the user has scrolled all the way to the bottom of the list. |
274
+ | (scroll) | Fired when scrolled (only when `[virtualScroll]="true"`). Provides the start and end index of the currently available items. Can be used for loading more items in chunks before the user has scrolled all the way to the bottom of the list. |
274
275
  | (scrollToEnd) | Fired when scrolled to the end of items. Can be used for loading more items in chunks. |
275
276
 
276
277
 
@@ -1436,16 +1436,17 @@ class ItemsList {
1436
1436
  return groups;
1437
1437
  }
1438
1438
  // Check if items are already grouped by given key.
1439
- if (Array.isArray(items[0].value[prop])) {
1439
+ const firstValue = items[0].value;
1440
+ if (firstValue != null && Array.isArray(firstValue[prop])) {
1440
1441
  for (const item of items) {
1441
- const children = (item.value[prop] || []).map((x, index) => this.mapItem(x, index));
1442
+ const children = (item.value?.[prop] || []).map((x, index) => this.mapItem(x, index));
1442
1443
  groups.set(item, children);
1443
1444
  }
1444
1445
  return groups;
1445
1446
  }
1446
1447
  const isFnKey = isFunction(this._ngSelect.groupBy());
1447
1448
  const keyFn = (item) => {
1448
- const key = isFnKey ? prop(item.value) : item.value[prop];
1449
+ const key = isFnKey ? prop(item.value) : item.value?.[prop];
1449
1450
  return isDefined(key) ? key : undefined;
1450
1451
  };
1451
1452
  // Group items by key.
@@ -1989,6 +1990,8 @@ class NgOptionComponent {
1989
1990
  this.disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : {}), transform: booleanAttribute });
1990
1991
  this.elementRef = inject((ElementRef));
1991
1992
  this.label = signal('', ...(ngDevMode ? [{ debugName: "label" }] : []));
1993
+ /** True when this component's inputs are initialized (after first change detection). */
1994
+ this.isInitialized = signal(false, ...(ngDevMode ? [{ debugName: "isInitialized" }] : []));
1992
1995
  afterEveryRender(() => {
1993
1996
  // Update label signal after render (innerHTML updated by template bindings)
1994
1997
  const currentLabel = (this.elementRef.nativeElement.innerHTML || '').trim();
@@ -1997,6 +2000,9 @@ class NgOptionComponent {
1997
2000
  }
1998
2001
  });
1999
2002
  }
2003
+ ngOnInit() {
2004
+ this.isInitialized.set(true);
2005
+ }
2000
2006
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: NgOptionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2001
2007
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.0", type: NgOptionComponent, isStandalone: true, selector: "ng-option", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `<ng-content />`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2002
2008
  }
@@ -2656,6 +2662,10 @@ class NgSelectComponent {
2656
2662
  _setItemsFromNgOptions() {
2657
2663
  effect(() => {
2658
2664
  const options = this.ngOptions();
2665
+ // Wait until all ng-option inputs are initialized (avoids _groupBy crash when values load async)
2666
+ if (options.length > 0 && !options.every((opt) => opt.isInitialized())) {
2667
+ return;
2668
+ }
2659
2669
  this.bindLabel.set(this._defaultLabel);
2660
2670
  const items = options.map((option) => ({
2661
2671
  $ngOptionValue: option.value(),