3

When droping an item I want to be able to perform an async call (e.g. check with backend for conflicts, collisions and so forth...) which returns true or false. If false, I want to "reverse" the drop so that the item appears in the original array.

I coulnd't find any references in the offical docs, so any pointers are appreciated on how to tackle this challenge.

Han Che
  • 8,239
  • 19
  • 70
  • 116
  • on `CdkDragDrop` event you will push into array then you want to make call and check if it returns `false` remove item from new array as you will have index `event.currentIndex` of item in new array and push it into old array you have previous index as well `event.previousIndex`. – indrajeet Jul 17 '19 at 15:23
  • From Angular material example, if you want to call `moveItemInArray(this.timePeriods, event.previousIndex, event.currentIndex);` it will sort the position within your array. Maybe if you only call this after receive a success from your API. – lmarcelocc Jul 17 '19 at 15:31
  • @Imarcelocc `event` will also give correct positions for different different arrays – indrajeet Jul 17 '19 at 15:39

2 Answers2

2

For anyone else looking for this, here's one way to do it. It would be great if the move could somehow be told to wait for the result before reverting, but I couldn't figure out how to do it.

try{
//Move the value first
transferArrayItem(event.previousContainer.data,
  event.container.data,
  event.previousIndex,
  event.currentIndex);

//Wait for the result and then roll back the change if required
this.openEdit(event.previousContainer.data[event.previousIndex]).subscribe((result:Updated) =>
  {

    if(result?.success !== 1){
      transferArrayItem(event.container.data,
        event.previousContainer.data,
        event.currentIndex,
        event.previousIndex);
    }

  });

}
Jim Jimson
  • 2,368
  • 3
  • 17
  • 40
0

Following the idea proposed by @Jim, a possible solution can be simply do the change and asynchronously check the status of the operation, if it is ok: done, otherwise revert the change, the following solution will work also using changeDetection: ChangeDetectionStrategy.OnPush

transferArrayItem(
    event.previousContainer.data,
    event.container.data,
    event.previousIndex,
    event.currentIndex);

this.service.asyncItem(itemToUpdate).toPromise().catch(() => {
    transferArrayItem(
          event.container.data,
          event.previousContainer.data,
          event.currentIndex,
          event.previousIndex);

    this.cdr.detectChanges();
});