Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ERROR TypeError: Cannot read property 'length' of undefined in Angular 7 Drag and Drop

I am just trying to create drag and drop component with the help of Angular 7 DragDropModule from @angular/cdk/drag-drop. But I am always getting the error as below.

HomeComponent.html:14 ERROR TypeError: Cannot read property 'length' of undefined
    at moveItemInArray (drag-drop.es5.js:1287)
    at HomeComponent.push../src/app/home/home.component.ts.HomeComponent.drop (home.component.ts:31)
    at Object.eval [as handleEvent] (HomeComponent.html:15)
    at handleEvent (core.js:19676)
    at callWithDebugContext (core.js:20770)
    at Object.debugHandleEvent [as handleEvent] (core.js:20473)
    at dispatchEvent (core.js:17125)
    at core.js:18615
    at SafeSubscriber.schedulerFn [as _next] (core.js:10218)
    at SafeSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.__tryOrUnsub (Subscriber.js:196)

Here is my HomeComponent.html

<div style="display: flex;">
  <div class="container">
    <div class="row">
      <h2 style="text-align: center">Movies</h2>
      <div  cdkDropList #allmovies="cdkDropList" [cdkDropListData]="movies" [cdkDropListConnectedTo]="[towatch]"
        (cdkDropListDropped)="drop($event)">
        <app-movie *ngFor="let movie of movies" [movie]="movie" cdkDrag></app-movie>
      </div>
    </div>
  </div>
  <div class="container">
    <div class="row">
      <h2 style="text-align: center">Movies to watch</h2>
      <div cdkDropList #towatch="cdkDropList" [cdkDropListConnectedTo]="[allmovies]"
        (cdkDropListDropped)="drop($event)">
        <app-movie *ngFor="let movie of moviesToWatch" [movie]="movie" cdkDrag></app-movie>
      </div>
    </div>
  </div>
</div>

And the HomeComponent.ts

export class HomeComponent {
  movies: Movie[];
  moviesToWatch: Movie[] = [{
    poster_path: '/uC6TTUhPpQCmgldGyYveKRAu8JN.jpg'
  }];
  constructor(private movieService: MovieService) {
    this.movieService.get(config.api.topRated)
      .subscribe((data) => {
        this.formatDta(JSON.parse(data._body).results);
      });
  }
  formatDta(_body: Movie[]): void {
    this.movies = _body.filter(movie => movie.poster_path !== '/uC6TTUhPpQCmgldGyYveKRAu8JN.jpg');
  }
  drop(event: CdkDragDrop<string[]>) {
    if (event.previousContainer === event.container) {
      moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
    } else {
      transferArrayItem(event.previousContainer.data,
        event.container.data,
        event.previousIndex,
        event.currentIndex);
    }
  }
}

I know I am missing something. But not sure, what it is. Any help is really appreciated.

like image 283
Sibeesh Venu Avatar asked Oct 29 '18 20:10

Sibeesh Venu


1 Answers

I found out what is the issue here. If you notice the code for the second container, in the div cdkDropList #toWatch="cdkDropList" I am missing the property [cdkDropListData] and it is mandatory one so I had to set [cdkDropListData]="moviesToWatch" as follows.

<div cdkDropList #toWatch="cdkDropList" [cdkDropListData]="moviesToWatch" [cdkDropListConnectedTo]="[allmovies]"
        (cdkDropListDropped)="drop($event)">
        <app-movie class="example-box" *ngFor="let movie of moviesToWatch" [movie]="movie" cdkDrag>{{movie}}</app-movie>
      </div>

After setting that, everything was working as expected.

like image 151
Sibeesh Venu Avatar answered Sep 20 '22 23:09

Sibeesh Venu