diff --git a/projects/igniteui-angular/grids/core/src/watch-changes.ts b/projects/igniteui-angular/grids/core/src/watch-changes.ts
index 38e079ff337..5ad882b2201 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 ee11fce0646..3ddbca93c77 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,
@@ -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;
@@ -4013,6 +4016,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(() => {
@@ -4249,6 +4257,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
@@ -6764,7 +6782,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();
@@ -6897,12 +6915,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 07b9e63e6c7..d10f59ff8df 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 680aeb0e56f..ce728f28fef 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
@@ -432,7 +432,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 aebbdbb6831..68e2b5265f0 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());