diff --git a/projects/igniteui-angular/grids/core/src/watch-changes.ts b/projects/igniteui-angular/grids/core/src/watch-changes.ts
index d4db75c573a..cbd4bb75f28 100644
--- a/projects/igniteui-angular/grids/core/src/watch-changes.ts
+++ b/projects/igniteui-angular/grids/core/src/watch-changes.ts
@@ -22,7 +22,8 @@ export function WatchChanges(): PropertyDecorator {
const oldValue = this[key];
if (val !== oldValue || (typeof val === 'object' && val === oldValue)) {
originalSetter.call(this, val);
- if (this.ngOnChanges && !init) {
+ // Explicitly check whether the decorator is called during initialization
+ if (this.ngOnChanges && init !== undefined && !init) {
// in case wacthed prop changes trigger ngOnChanges manually
const changes: SimpleChanges = {
[key]: new SimpleChange(oldValue, val, false)
diff --git a/projects/igniteui-angular/grids/grid/src/grid-base.directive.ts b/projects/igniteui-angular/grids/grid/src/grid-base.directive.ts
index 8c8eb802ce1..55e196509a9 100644
--- a/projects/igniteui-angular/grids/grid/src/grid-base.directive.ts
+++ b/projects/igniteui-angular/grids/grid/src/grid-base.directive.ts
@@ -30,7 +30,9 @@ import {
ViewContainerRef,
DOCUMENT,
inject,
- InjectionToken
+ InjectionToken,
+ SimpleChanges,
+ OnChanges
} from '@angular/core';
import {
areEqualArrays,
@@ -109,7 +111,7 @@ import { IgxGridGroupByAreaComponent } from './grouping/grid-group-by-area.compo
import { IgxPaginatorToken, type IgxPaginatorComponent } from 'igniteui-angular/paginator';
import { IgxSnackbarComponent } from 'igniteui-angular/snackbar';
import { CharSeparatedValueData, DropPosition, FilterMode, getUUID, GridCellMergeMode, GridKeydownTargetType, GridPagingMode, GridSelectionMode, GridSelectionRange, GridServiceType, GridSummaryPosition, GridType, GridValidationTrigger, IActiveNode, IActiveNodeChangeEventArgs, ICellPosition, IClipboardOptions, IColumnMovingEndEventArgs, IColumnMovingEventArgs, IColumnMovingStartEventArgs, IColumnResizeEventArgs, IColumnsAutoGeneratedEventArgs, IColumnSelectionEventArgs, IColumnVisibilityChangedEventArgs, IColumnVisibilityChangingEventArgs, IFilteringEventArgs, IGridCellEventArgs, IGridClipboardEvent, IGridContextMenuEventArgs, IGridEditDoneEventArgs, IGridEditEventArgs, IGridFormGroupCreatedEventArgs, IGridKeydownEventArgs, IGridRowEventArgs, IGridScrollEventArgs, IGridToolbarExportEventArgs, IGridValidationStatusEventArgs, IGX_GRID_SERVICE_BASE, IgxAdvancedFilteringDialogComponent, IgxCell, IgxColumnComponent, IgxColumnGroupComponent, IgxColumnResizingService, IgxDragIndicatorIconDirective, IgxEditRow, IgxExcelStyleHeaderIconDirective, IgxExcelStyleLoadingValuesTemplateDirective, IgxFilteringService, IgxGridBodyDirective, IgxGridCellComponent, IgxGridColumnResizerComponent, IgxGridEmptyTemplateContext, IgxGridEmptyTemplateDirective, IgxGridExcelStyleFilteringComponent, IgxGridFilteringCellComponent, IgxGridFilteringRowComponent, IgxGridHeaderComponent, IgxGridHeaderGroupComponent, IgxGridHeaderRowComponent, IgxGridHeaderTemplateContext, IgxGridLoadingTemplateDirective, IgxGridNavigationService, IgxGridPinningActionsComponent, IgxGridRowDragGhostContext, IgxGridRowEditActionsTemplateContext, IgxGridRowEditTemplateContext, IgxGridRowEditTextTemplateContext, IgxGridRowTemplateContext, IgxGridSelectionService, IgxGridSummaryService, IgxGridTemplateContext, IgxGridToolbarComponent, IgxGridTransaction, IgxGridValidationService, IgxHeaderCollapsedIndicatorDirective, IgxHeaderExpandedIndicatorDirective, IgxHeadSelectorDirective, IgxHeadSelectorTemplateContext, IgxRowAddTextDirective, IgxRowCollapsedIndicatorDirective, IgxRowDirective, IgxRowDragGhostDirective, IgxRowEditActionsDirective, IgxRowEditTabStopDirective, IgxRowEditTemplateDirective, IgxRowEditTextDirective, IgxRowExpandedIndicatorDirective, IgxRowSelectorDirective, IgxRowSelectorTemplateContext, IgxSortAscendingHeaderIconDirective, IgxSortDescendingHeaderIconDirective, IgxSortHeaderIconDirective, IgxSummaryRowComponent, IgxToolbarToken, IPinColumnCancellableEventArgs, IPinColumnEventArgs, IPinningConfig, IPinRowEventArgs, IRowDataCancelableEventArgs, IRowDataEventArgs, IRowDragEndEventArgs, IRowDragStartEventArgs, IRowSelectionEventArgs, IRowToggleEventArgs, ISearchInfo, ISizeInfo, ISortingEventArgs, RowEditPositionStrategy, RowPinningPosition, RowType, WatchChanges } from 'igniteui-angular/grids/core';
-import { getCurrentI18n, getNumberFormatter, IResourceChangeEventArgs, } from 'igniteui-i18n-core';
+import { getCurrentI18n, getNumberFormatter, IResourceChangeEventArgs } from 'igniteui-i18n-core';
import { I18N_FORMATTER } from 'igniteui-angular/core';
/**
@@ -138,7 +140,7 @@ const MINIMUM_COLUMN_WIDTH = 136;
wcSkipComponentSuffix */
@Directive()
export abstract class IgxGridBaseDirective implements GridType,
- OnInit, DoCheck, OnDestroy, AfterContentInit, AfterViewInit {
+ OnInit, DoCheck, OnDestroy, AfterContentInit, AfterViewInit, OnChanges {
/* blazorSuppress */
public readonly validation = inject(IgxGridValidationService);
@@ -196,6 +198,7 @@ export abstract class IgxGridBaseDirective implements GridType,
*
* ```
*/
+ @WatchChanges()
@Input({ transform: booleanAttribute })
public autoGenerate = false;
@@ -4033,6 +4036,11 @@ export abstract class IgxGridBaseDirective implements GridType,
}
this.setupColumns();
+ this.columnList.changes
+ .pipe(takeUntil(this.destroy$))
+ .subscribe((change: QueryList) => {
+ this.onColumnsChanged(change);
+ });
this.toolbar.changes.pipe(filter(() => !this._init), takeUntil(this.destroy$)).subscribe(() => this.notifyChanges(true));
this.setUpPaginator();
this.paginationComponents.changes.pipe(takeUntil(this.destroy$)).subscribe(() => {
@@ -4047,8 +4055,8 @@ export abstract class IgxGridBaseDirective implements GridType,
const activeRow = this.navigation.activeNode?.row;
const selectedCellIndexes = this.selectionService.selection
- ? Array.from(this.selectionService.selection.keys())
- : [];
+ ? Array.from(this.selectionService.selection.keys())
+ : [];
this._activeRowIndexes = [activeRow, ...selectedCellIndexes];
return this._activeRowIndexes;
}
@@ -4269,6 +4277,16 @@ export abstract class IgxGridBaseDirective implements GridType,
}
}
+ /**
+ * @hidden @internal
+ */
+ public ngOnChanges(changes: SimpleChanges) {
+ if (!changes.autoGenerate?.firstChange && changes.autoGenerate?.currentValue && this.data?.length > 0 && this.columnList?.length === 0 && this.columns.length === 0) {
+ // Make sure to setup columns only after the grid is initialized and autoGenerate is changed
+ this.setupColumns();
+ }
+ }
+
/**
* @hidden
* @internal
@@ -6784,7 +6802,7 @@ export abstract class IgxGridBaseDirective implements GridType,
} else if (this.width !== null) {
this._columnWidth = Math.max(parseFloat(possibleWidth), this.minColumnWidth) + 'px'
} else {
- this._columnWidth = this.minColumnWidth + 'px';
+ this._columnWidth = this.minColumnWidth + 'px';
}
}
this._updateColumnDefaultWidths();
@@ -6917,12 +6935,6 @@ export abstract class IgxGridBaseDirective implements GridType,
this.initColumns(this._columns, (col: IgxColumnComponent) => this.columnInit.emit(col));
this.columnListDiffer.diff(this.columnList);
this._calculateRowCount();
-
- this.columnList.changes
- .pipe(takeUntil(this.destroy$))
- .subscribe((change: QueryList) => {
- this.onColumnsChanged(change);
- });
}
protected getColumnList() {
diff --git a/projects/igniteui-angular/grids/grid/src/grid.component.spec.ts b/projects/igniteui-angular/grids/grid/src/grid.component.spec.ts
index dcdb16a7f1a..decc6e1a448 100644
--- a/projects/igniteui-angular/grids/grid/src/grid.component.spec.ts
+++ b/projects/igniteui-angular/grids/grid/src/grid.component.spec.ts
@@ -95,6 +95,25 @@ describe('IgxGrid Component Tests #grid', () => {
expect(fix.componentInstance.columnEventCount).toEqual(4);
});
+ it('should initialize a grid with data and columns if autoGenerate is set after the data', () => {
+ const fix = TestBed.createComponent(IgxGridTestComponent);
+ fix.componentInstance.data = [
+ { Number: 1, String: '1', Boolean: true, Date: new Date(Date.now()) }
+ ];
+ fix.componentInstance.columns = [];
+ fix.detectChanges();
+
+ const grid = fix.componentInstance.grid;
+
+ expect(grid.columns.length).toBe(0);
+
+ fix.componentInstance.autoGenerate = true;
+ fix.detectChanges();
+
+ expect(grid.columns.length).toBe(4);
+ expect(grid.rowList.length).toBe(1);
+ });
+
it('should initialize a grid and change column properties during initialization', () => {
const fix = TestBed.createComponent(IgxGridTestComponent);
fix.componentInstance.columns = [];
diff --git a/projects/igniteui-angular/grids/hierarchical-grid/src/row-island.component.ts b/projects/igniteui-angular/grids/hierarchical-grid/src/row-island.component.ts
index 5fcbc19aa06..7376a3049fa 100644
--- a/projects/igniteui-angular/grids/hierarchical-grid/src/row-island.component.ts
+++ b/projects/igniteui-angular/grids/hierarchical-grid/src/row-island.component.ts
@@ -468,7 +468,7 @@ export class IgxRowIslandComponent extends IgxHierarchicalGridBaseDirective
/**
* @hidden
*/
- public ngOnChanges(changes) {
+ public override ngOnChanges(changes) {
this.layoutChange.emit(changes);
if (!this.isInit) {
this.initialChanges.push(changes);
diff --git a/projects/igniteui-angular/grids/pivot-grid/src/pivot-grid.component.ts b/projects/igniteui-angular/grids/pivot-grid/src/pivot-grid.component.ts
index 5a3d920d719..f8c15501068 100644
--- a/projects/igniteui-angular/grids/pivot-grid/src/pivot-grid.component.ts
+++ b/projects/igniteui-angular/grids/pivot-grid/src/pivot-grid.component.ts
@@ -1020,7 +1020,7 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni
/**
* @hidden @internal
*/
- public ngOnChanges(changes: SimpleChanges) {
+ public override ngOnChanges(changes: SimpleChanges) {
if (changes.superCompactMode && !changes.superCompactMode.isFirstChange()) {
this._shouldUpdateSizes = true;
resizeObservable(this.verticalScrollContainer.displayContainer).pipe(take(1), takeUntil(this.destroy$)).subscribe(() => this.resizeNotify.next());