Type 'Event' is missing the following properties from type 'CdkDragDrop<string [], string[]>'

Issue

I’m looking at the reorderable columns example on stackblitz.

In particular I see the html

<table mat-table
       [dataSource]="dataSource" 
       cdkDropList
       cdkDropListOrientation="horizontal"
       (cdkDropListDropped)="drop($event)">

I’ve defined the drop inside MytableComponent

export class MytableComponent implements AfterViewInit {
  @ViewChild(MatPaginator) paginator!: MatPaginator;
  @ViewChild(MatSort) sort!: MatSort;
  @ViewChild(MatTable) table!: MatTable<MytableItem>;
  dataSource: MytableDataSource;

  /** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */
  displayedColumns = ['id', 'name', 'dateOfBirth'];

  drop(event: CdkDragDrop<string[]>) {
    moveItemInArray(this.displayedColumns, event.previousIndex, event.currentIndex);
  }

  constructor() {
    this.dataSource = new MytableDataSource();
  }

  ngAfterViewInit(): void {
    this.dataSource.sort = this.sort;
    this.dataSource.paginator = this.paginator;
    this.table.dataSource = this.dataSource;
  }
}

The build fails with an error

Error: src/app/mytable/mytable.component.html:5:35 - error TS2345: Argument of type 'Event' is not assignable to parameter of type 'CdkDragDrop<string[], string[]>'.
  Type 'Event' is missing the following properties from type 'CdkDragDrop<string[], string[]>': previousIndex, currentIndex, item, container, and
3 more.

Solution

Maybe I have set a stricter type checking than the example in the initial settings of the project.

After a search I see that

  drop(event: Event)  {
      if (isDragDrop(event)) {
        moveItemInArray(this.displayedColumns, event.previousIndex, event.currentIndex);
      }
    }

compiles successfully, when I declare a

function isDragDrop(object: any): object is CdkDragDrop<string[]> {
  return 'previousIndex' in object;
}

Of course I have to import the DragDropModule in the app.module.ts
and now I can reorder the columns

BTW, it is also possible to load and save the columns’ order from local storage with convenient helpers, for example – with an @Input() ID: string | undefined; – in mytable.component.ts I’ve added also:

  onSaveOrder() {
    if (!this.ID) {
      console.log('my-table ID not set!');
      return;
    }
    localStorage.setItem('my-table-cols-' + this.ID, this.displayedColumns.join(','));
    console.log(`table ID ${ this.ID } columns order saved ${ this.displayedColumns }`);
  }
  onLoadOrder() {
    if (!this.ID) {
      console.log('my-table ID not set!');
      return;
    }
    const saved = localStorage.getItem('my-table-cols-' + this.ID);
    if (saved) {
      this.displayedColumns = saved.split(',');  
      console.log(`table ID ${ this.ID } columns order loaded ${saved}`);
    } else {
      console.log(`table ID ${ this.ID } nothing was saved`);
    }
  }

Usage in app.component.html

  <h3>My Table Rowss</h3>
  <app-mytable ID="MyTable1"></app-mytable>

Answered By – user11323942

Answer Checked By – Katrina (AngularFixing Volunteer)

Leave a Reply

Your email address will not be published.