title: Angular8 drag and drop problem with drag and drop with multiple cases
body: <p>I am working with Angular8 Drag and Drop and come across some problem</p>
  
  <p>What is my concept and what I am doing</p>
  
  <ol>
  <li>Truck in which I drag and drop deliveries</li>
  <li>Deliveries in which I drag and drop packages
  this are working fine</li>
  </ol>
  
  <p>I am using following JSON data structute(shown below) which is get updated with <code>moveItemInArray</code> and <code>transferArrayItem</code> function</p>
  
  <pre><code>trucks = [{
      "..": '',
      "Deliveries": [{
          "..": '',
          "Packages": [{
  
          }, {}, {}, ....]
      }, {}, {}, ....]
  }, {}, {}, ....]
  </code></pre>
  
  <p>Everything works fine but I need some extra things to be applied with drag and drop that is,</p>
  
  <ol>
  <li><p>I want a package to be directly dropped inside truck...so when a package is directly dropped into the truck I want to add a delivery object in that truck deliveries and then inside that delivery, I want to assign the drop package</p></li>
  <li><p>I want delivery to be directly dropped inside the delivery...so when delivery is directly dropped I want to move all package of previous delivery packages to current delivery</p></li>
  </ol>
  
  <p>I have tried a lot with different things but drag and drop get disturbed and miss behaves</p>
  
  <p>Below are my ts and HTML template code</p>
  
  <pre><code>import { Component, Input, OnInit } from '@angular/core';
  import { CdkDragDrop, moveItemInArray, transferArrayItem } from '@angular/cdk/drag-drop';
  
  import { ModelTruck } from '../../core/models/model-truck';
  import { ModelDelivery } from '../../core/models/model-delivery';
  import { ModelPackage } from '../../core/models/model-package';
  
  @Component({
      selector: 'app-manual',
      templateUrl: './manual.component.html',
      styleUrls: ['./manual.component.css']
  })
  
  export class ManualComponent implements OnInit {
  
      @Input() packages: ModelPackage[];
      @Input() trucks: ModelTruck[];
      @Input() deliveries: ModelDelivery[];
  
      /**
       * Trucks inside work area
       */
      workTrucks = [];
  
      /**
       * Deliveries drop inside trucks connected element IDs
       */
      truckIds = ['no-trucks'];
  
      /**
       * Packages drop inside deliveries connected element IDs
       */
      deliveryIds = ['no-delivery'];
  
      /**
       * Column from which we are applying filter
       */
      column: any = 'Km';
  
      /**
       * Direction use for filter ASC or DESC
       */
      direction = 1;
  
      /**
       * Choosed truck/delivery/package data
       */
      choosed = {
          '1': '-',
          '2': '-',
          '3': '-',
          '4': '-',
          '5': '-',
          '6': '-',
          '7': '-',
          '8': '-',
          '9': '-',
          '10': '-',
          '11': '-',
          '12': '-',
          '13': '-',
          '14': '-',
          '15': '-',
          '16': '-',
          '17': '-',
          '18': '-',
          '19': '-',
          '20': '-',
          '..': '..',
      };
  
      /**
       * Initializing constructor
       */
      ngOnInit() {
  
          this._createConnectedIds();
          this._calculateAllStuff();
      }
  
      /**
       * Creating connected link Ids for the drag and drop elements
       */
      _createConnectedIds() {
  
          // For the deliveries to be drag and drop
          for (let truck of this.trucks) {
              this.truckIds.push(`truck-${truck.ID}`);
              for (let delivery of truck.Deliveries) {
                  this.deliveryIds.push(`delivery-${delivery.ID}`);
              }
          }
  
          // For the packages to be drag and drop
          for (let delivery of this.deliveries) {
              this.deliveryIds.push(`delivery-${delivery.ID}`);
          }
      }
  
      /**
       * Onchange sort by
       */
      doSort(sort) {
          this.direction = sort == 'ASC' ? 1 : -1;
      }
  
      /**
       * Onchange filter by
       */
      doFilter(filter) {
          this.column = filter;
      }
  
      /**
       * Event on drop the packages
       */
      onPackageDrop(event: CdkDragDrop&lt;string[]&gt;) {
  
          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);
          }
  
          this._calculateAllStuff();
      }
  
      /**
       * Event on drop the deliveries
       */
      onDeliveryDrop(event: CdkDragDrop&lt;string[]&gt;) {
  
          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);
          }
  
          this._calculateAllStuff();
      }
  
      /**
       * Event on drop the trucks
       */
      onTruckDrop(event: CdkDragDrop&lt;string[]&gt;) {
  
          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);
          }
  
          this._calculateAllStuff();
      }
  
      /**
       * Calculate all the stuffs
       * Related to weight, volume, cost and number of packages etc
       */
      _calculateAllStuff() {
  
          this._removeDeliveriesWithoutPackage();
          this._calculateTrucksStuff();
          this._calculateDeliveriesStuff(this.deliveries);
  
          console.log('-----------------------');
          console.log('Trucks Inside The List');
          console.log(this.trucks);
          console.log('Trucks Inside Work Area');
          console.log(this.workTrucks);
      }
  
      /**
       * Remove deliveries without package
       */
      _removeDeliveriesWithoutPackage() {
  
          // Remove deliveries not contains package (Deliveries area)
          this.deliveries = (this.deliveries).filter(function(obj) {
              return obj.Packages.length != 0;
          });
  
          // Remove deliveries not contains package (Work Area)
          for( let truck of this.workTrucks ) {
              truck.Deliveries = (truck.Deliveries).filter(function(obj) {
                  return obj.Packages.length != 0;
              });
          }
      }
  
      /**
       * Calculate package related stuffs
       * Related to weight, volume, cost and number of pieces etc
       */
      _calculatePackagesStuff(packages) {
  
          let packageStuffs = {
              ActualWeightDry: packages.filter((obj) =&gt; obj.TypePackage === 'dry').length,
              ActualWeightCold: packages.filter((obj) =&gt; obj.TypePackage === 'cold').length,
              ActualWeight: 0,
              ActualVolume: 0,
              ActualCostMerchandise: 0,
              NumberPackages: packages.length,
              NumberPieces: 0
          };
  
          for( let item of packages ) {
              packageStuffs.ActualWeight += item.ActualWeight;
              packageStuffs.ActualVolume += item.ActualVolume;
              packageStuffs.ActualCostMerchandise += item.ActualCostMerchandise;
              packageStuffs.NumberPieces += item.NumberPieces;
          }
  
          return packageStuffs;
      }
  
      /**
       * Calculate deliveries related stuffs
       * Related to weight, volume, cost and number of pieces etc
       */
      _calculateDeliveriesStuff(deliveries) {
  
          let deliveryStuffs = {
              MaxCostMerchadise: 0,
              ActualWeight: 0,
              ActualVolume: 0,
              NumberDestinations: deliveries.length,
              ActualCostMerchandise: 0,
              NumberPackages: 0,
              NumberPieces: 0,
              Trip: 0
          };
  
          for( let delivery of deliveries ) {
              deliveryStuffs.MaxCostMerchadise += delivery.MaxCostMerchadise;
              deliveryStuffs.ActualWeight += delivery.ActualWeight;
              deliveryStuffs.ActualVolume += delivery.ActualVolume;
              deliveryStuffs.ActualCostMerchandise += delivery.ActualCostMerchandise;
              deliveryStuffs.NumberPackages += delivery.Packages.length;
              deliveryStuffs.NumberPieces += delivery.NumberPieces;
              deliveryStuffs.Trip += delivery.Trip;
  
              let packageStuffs = this._calculatePackagesStuff(delivery.Packages);
              let keys = Object.keys(packageStuffs);
              for( let key of keys ) {
                  delivery[key] = packageStuffs[key];
              }
          }
  
          return deliveryStuffs;
      }
  
      /**
       * Calculate trucks related stuffs for both work and in list
       * Related to weight, volume, cost and number of pieces etc
       */
      _calculateTrucksStuff() {
          this._calculateForTruck(this.trucks);
          this._calculateForTruck(this.workTrucks);
      }
  
      /**
       * Calculate truck stuff
       * Resulable code
       */
      _calculateForTruck(trucks) {
          for( let truck of trucks ) {
              let deliveryStuffs = this._calculateDeliveriesStuff(truck.Deliveries);
              let keys = Object.keys(deliveryStuffs);
              for( let key of keys ) {
                  truck[key] = deliveryStuffs[key];
              }
          }
      }
  
      /**
       * Recalculating time
       */
      doRecalcTime() {
          alert('Doing recalculate time[need to implement]');
      }
  
      /**
       * Recalculating the order
       */
      doRecalcOrder() {
          alert('Doing recalculate order[need to implement]');
      }
  
      /**
       * Choosed element
       */
      choose(elem) {
          this.choosed = elem;
      }
  
      /**
       * Choosed element keys only
       */
      choosedKeys() {
          return Object.keys(this.choosed);
      }
  
      /**
       * Check if object
       */
      isItObject(elem) {
          return elem instanceof Object;
      }
  }
  
  </code></pre>
  
  <pre><code>&lt;div class="main"&gt;
      &lt;div class="width-20 truck-lists"&gt;
          &lt;div class="sorting"&gt;
              &lt;div class="sort-filters"&gt;
                  &lt;select (change)="doFilter($event.target.value)"&gt;
                      &lt;option value=""&gt;Filter By&lt;/option&gt;
                      &lt;option value="TypeVehicle"&gt;TypeVehicle&lt;/option&gt;
                      &lt;option value="MaxWeight"&gt;MaxWeight&lt;/option&gt;
                      &lt;option value="MaxVolume"&gt;MaxVolume&lt;/option&gt;
                      &lt;option value="Km"&gt;Km&lt;/option&gt;
                      &lt;option value="Cost"&gt;Cost&lt;/option&gt;
                  &lt;/select&gt;
              &lt;/div&gt;
              &lt;div class="asc-or-desc" (change)="doSort($event.target.value)"&gt;
                  &lt;select&gt;
                      &lt;option value=""&gt;Sort By&lt;/option&gt;
                      &lt;option value="ASC"&gt;ASC&lt;/option&gt;
                      &lt;option value="DESC"&gt;DESC&lt;/option&gt;
                  &lt;/select&gt;
              &lt;/div&gt;
          &lt;/div&gt;
          &lt;ul 
              cdkDropList 
              #truckArea="cdkDropList"
              [cdkDropListData]="trucks" 
              [cdkDropListConnectedTo]="[workArea]" 
              (cdkDropListDropped)="onTruckDrop($event)"&gt;
              &lt;li 
                  cdkDrag
                  *ngFor="let truck of trucks | orderBy: {property: column, direction: direction}"
                  class="truck-item"
                  (click)="choose(truck)"&gt;
                  &lt;div class="truck-item-content"&gt;
                      {{ truck.TypeVehicle }} 
                      #{{ truck.ID }} | 
                      {{ truck.NumberDestinations }} Deliveries | 
                      {{ truck.NumberPackages }} Packages | 
                      {{ truck.Km }} Km | 
                      ${{ truck.Cost }}
                  &lt;/div&gt;
  
                  &lt;ol type="i"&gt;
                     &lt;li *ngFor="let delivery of truck.Deliveries"&gt;
                         {{ delivery.State }}, {{ delivery.DestinationTR1 }}
                     &lt;/li&gt;
                  &lt;/ol&gt;
  
                  &lt;span class="truck-size-tag"&gt;{{ truck.ID }}&lt;/span&gt;
              &lt;/li&gt;
          &lt;/ul&gt;
      &lt;/div&gt;
      &lt;div class="width-60 truck-works"&gt;
          &lt;div class="truck-works-dashboard"&gt;
              &lt;ul 
                  cdkDropList 
                  #workArea="cdkDropList"
                  [cdkDropListData]="workTrucks" 
                  [cdkDropListConnectedTo]="[truckArea]"
                  (cdkDropListDropped)="onTruckDrop($event)"&gt;
                  &lt;li 
                      cdkDrag
                      *ngFor="let truck of workTrucks"
                      class="truck-item truck-item-in-dashboard"
                      (click)="choose(truck)"&gt;
                      &lt;div class="truck-item-content"&gt;
                          {{ truck.TypeVehicle }} 
                          #{{ truck.ID }} | 
                          {{ truck.NumberDestinations }} Deliveries | 
                          {{ truck.NumberPackages }} Packages | 
                          {{ truck.Km }} Km | 
                          ${{ truck.Cost }}
                      &lt;/div&gt;
                      &lt;div class="truck-row"&gt;
                          &lt;div class="only-deliveries"&gt;
                              &lt;ul 
                                  cdkDropList 
                                  [cdkDropListData]="truck.Deliveries" 
                                  cdkDropListOrientation="horizontal" 
                                  [cdkDropListConnectedTo]="truckIds" 
                                  id="truck-{{ truck.ID }}" 
                                  (cdkDropListDropped)="onDeliveryDrop($event)"&gt;
                                  &lt;li 
                                      cdkDrag
                                      *ngFor="let delivery of truck.Deliveries"
                                      class="delivery-item"
                                      (click)="$event.stopPropagation(); choose(delivery)"&gt;
                                      &lt;div class="delivery-name"&gt;
                                          {{ delivery.State }} - {{ delivery.DestinationTR1 }}
                                      &lt;/div&gt;
                                      &lt;div class="delivery-time"&gt;
                                          {{ delivery.Delivery }}
                                      &lt;/div&gt;
                                      &lt;ul 
                                          cdkDropList 
                                          [cdkDropListData]="delivery.Packages" 
                                          [cdkDropListConnectedTo]="deliveryIds" 
                                          cdkDropListOrientation="horizontal"  
                                          (cdkDropListDropped)="onPackageDrop($event)" 
                                          id="delivery-{{ delivery.ID }}"&gt;
                                          &lt;li 
                                              cdkDrag
                                              *ngFor="let package of delivery.Packages"
                                              [ngClass]="package.Type == 'Urgent' ? 'package-item urgent' : 'package-item'"
                                              (click)="$event.stopPropagation(); choose(package)"&gt;
                                              Pack #{{ package.ID }}&lt;br&gt;
                                              {{ package.Type }}
                                          &lt;/li&gt;
                                      &lt;/ul&gt;
                                  &lt;/li&gt;
                              &lt;/ul&gt;
                          &lt;/div&gt;
                          &lt;div class="only-dashboard"&gt;
                              &lt;table&gt;
                                  &lt;thead&gt;
                                      &lt;tr&gt;
                                          &lt;th&gt;Restriction&lt;/th&gt;
                                          &lt;th&gt;Kg&lt;/th&gt;
                                          &lt;th&gt;m3&lt;/th&gt;
                                          &lt;th&gt;$&lt;/th&gt;
                                          &lt;th&gt;Access&lt;/th&gt;
                                          &lt;th&gt;Minutes&lt;/th&gt;
                                          &lt;th&gt;Incomp&lt;/th&gt;
                                      &lt;/tr&gt;
                                  &lt;/thead&gt;
                                  &lt;tbody&gt;
                                      &lt;tr&gt;
                                          &lt;th&gt;Actual&lt;/th&gt;
                                          &lt;td&gt;{{ truck.ActualWeight }}&lt;/td&gt;
                                          &lt;td&gt;{{ truck.ActualVolume }}&lt;/td&gt;
                                          &lt;td&gt;${{ truck.ActualCostMerchandise }}&lt;/td&gt;
                                          &lt;td&gt;-&lt;/td&gt;
                                          &lt;td&gt;-&lt;/td&gt;
                                          &lt;td&gt;-&lt;/td&gt;
                                      &lt;/tr&gt;
                                      &lt;tr&gt;
                                          &lt;th&gt;Max&lt;/th&gt;
                                          &lt;td&gt;{{ truck.MaxWeight }}&lt;/td&gt;
                                          &lt;td&gt;{{ truck.MaxVolume }}&lt;/td&gt;
                                          &lt;td&gt;${{ truck.MaxCostMerchadise }}&lt;/td&gt;
                                          &lt;td&gt;-&lt;/td&gt;
                                          &lt;td&gt;-&lt;/td&gt;
                                          &lt;td&gt;-&lt;/td&gt;
                                      &lt;/tr&gt;
                                      &lt;tr&gt;
                                          &lt;th&gt;Available&lt;/th&gt;
                                          &lt;td&gt;
                                              {{ truck.MaxWeight - truck.ActualWeight }}
                                          &lt;/td&gt;
                                          &lt;td&gt;
                                              {{ truck.MaxVolume - truck.ActualVolume }}
                                          &lt;/td&gt;
                                          &lt;td&gt;
                                              ${{ truck.MaxCostMerchadise - truck.ActualCostMerchandise }}
                                          &lt;/td&gt;
                                          &lt;td&gt;-&lt;/td&gt;
                                          &lt;td&gt;-&lt;/td&gt;
                                          &lt;td&gt;-&lt;/td&gt;
                                      &lt;/tr&gt;
                                      &lt;tr&gt;
                                          &lt;th&gt;%Available&lt;/th&gt;
                                          &lt;td&gt;-&lt;/td&gt;
                                          &lt;td&gt;-&lt;/td&gt;
                                          &lt;td&gt;-&lt;/td&gt;
                                          &lt;td&gt;-&lt;/td&gt;
                                          &lt;td&gt;-&lt;/td&gt;
                                          &lt;td&gt;-&lt;/td&gt;
                                      &lt;/tr&gt;
                                  &lt;/tbody&gt;
                              &lt;/table&gt;
                          &lt;/div&gt;
                      &lt;/div&gt;
                      &lt;span class="truck-size-tag"&gt;{{ truck.ID }}&lt;/span&gt;
                  &lt;/li&gt;
              &lt;/ul&gt;
          &lt;/div&gt;
          &lt;div class="no-truck-deliveries"&gt;
              &lt;h4&gt;No Truck&lt;/h4&gt;
              &lt;ul 
                  cdkDropList 
                  [cdkDropListData]="deliveries" 
                  cdkDropListOrientation="horizontal" 
                  [cdkDropListConnectedTo]="truckIds"
                  (cdkDropListDropped)="onDeliveryDrop($event)" 
                  id="no-trucks"
                  class="no-truck"&gt;
                  &lt;li 
                      cdkDrag
                      *ngFor="let delivery of deliveries"
                      class="delivery-item"
                      (click)="choose(delivery)"&gt;
                      &lt;div class="delivery-name"&gt;
                          {{ delivery.State }} - {{ delivery.DestinationTR1 }}
                      &lt;/div&gt;
                      &lt;div class="delivery-time"&gt;
                          {{ delivery.Delivery }}
                      &lt;/div&gt;
                      &lt;ul 
                          cdkDropList 
                          [cdkDropListData]="delivery.Packages" 
                          [cdkDropListConnectedTo]="deliveryIds" 
                          cdkDropListOrientation="horizontal"  
                          (cdkDropListDropped)="onPackageDrop($event)" 
                          id="delivery-{{ delivery.ID }}"&gt;
                          &lt;li 
                              cdkDrag
                              *ngFor="let package of delivery.Packages"
                              [ngClass]="package.Type == 'Urgent' ? 'package-item urgent' : 'package-item'"
                              (click)="$event.stopPropagation(); choose(package)"&gt;
                              Pack #{{ package.ID }}&lt;br&gt;
                              {{ package.Type }}
                          &lt;/li&gt;
                      &lt;/ul&gt;
                  &lt;/li&gt;
              &lt;/ul&gt;
          &lt;/div&gt;
      &lt;/div&gt;
      &lt;div class="width-20 truck-datas"&gt;
          &lt;div class="action-buttons"&gt;
              &lt;button class="btn"&gt;Import&lt;/button&gt;
              &lt;button class="btn"&gt;Export&lt;/button&gt;
          &lt;/div&gt;
          &lt;div class="element-datasets"&gt;
              &lt;table&gt;
                  &lt;tr *ngFor="let key of choosedKeys()"&gt;
                      &lt;th [hidden]="isItObject(choosed[key])"&gt;{{ key }}&lt;/th&gt;
                      &lt;td [hidden]="isItObject(choosed[key])"&gt;{{ choosed[key] }}&lt;/td&gt;
                  &lt;/tr&gt;
              &lt;/table&gt;
          &lt;/div&gt;
          &lt;div class="action-buttons"&gt;
              &lt;button class="btn" (click)="doRecalcTime()"&gt;Recalculate Time&lt;/button&gt;
              &lt;button class="btn" (click)="doRecalcOrder()"&gt;Recalculate Order&lt;/button&gt;
          &lt;/div&gt;
      &lt;/div&gt;
  &lt;/div&gt;
  
  </code></pre>