Search code examples
angularangular5angularfire2

Missed key in loop (angular 5)


I can not get the key to edit or delete. I have all the values of the loop but not the key. In console I do not have any error

invoice-list.component

export class InvoiceListComponent implements OnInit {
invoiceList: IInvoice[];

constructor(private invoiceService: InvoiceService) { }

ngOnInit() {
  this.invoiceService.getInvoices().snapshotChanges()
    .map(data  => data.map(datum => datum.payload.toJSON()))
    .map((data : IInvoice[]) => {
        return data.map(datum => {
          let purchases = [];          

          for(let key in datum.purchases) {
              purchases.push(datum.purchases[key]);
          }
          datum.purchases = purchases;
          return datum;
        });
    })
    .subscribe(data => this.invoiceList = data);      
}

onDelete($key: string){
  //console.log($key)
  this.invoiceService.deleteInvoice($key);
 }
}

invoice-list.html

<table class="table table-sm table-hover table-bordered ">
        <thead class="thead-light">
            <tr>
              <th scope="col">Name</th>
              <th scope="col">Total</th>
              <th scope="col">Vendor</th>
              <th scope="col">Date</th>
              <th scope="col">Purchases</th>
              <th scope="col">Action</th>
            </tr>
          </thead>
      <tbody>
        <tr *ngFor="let invoice of invoiceList">                
          <td>{{invoice.customer.name}} {{invoice.customer.lastname}}</td>
          <td>{{invoice.totalPrice}}</td>
          <td>{{invoice.uid}}</td> 
          <td>{{invoice.createdAt}}</td>   
          <td>
              <li class="list-group-item"
              *ngFor="let purchase of invoice.purchases">
                  {{purchase.product.name}}
              </li>
          </td>
          <td>
            <a class="btn btn-danger text-white" (click)="onDelete(invoice.$key)">
              <i class="fas fa-trash-alt"></i>

            </a>
        </td>    
        </tr>
      </tbody>
    </table>

any help?

here's example (login => user:user@user.com | pass: user123) StackBlitz


Solution

  • The issue is that value of $key is undefined. When you do datum.payload.toJSON(), you lose the $key

    Instead, you can use:

      ngOnInit() {
        this.invoiceService.getInvoices().snapshotChanges()
          .map(data => data.map(datum => {
            let purchases = datum.payload.toJSON()['purchases'];
            return {
              ...datum.payload.toJSON() as IInvoice,
              $key: datum.key,
              purchases: Object.keys(purchases).map(key => purchases[key])
            }
          }))
          .subscribe(data => this.invoiceList = data);
      }
    

    By using ...datum.payload.toJSON(), we can copy over all of the values from that object, and in the line below we can also add the $key. Finally, the line below that converts purchases from an Object into an Array.

    Here is a StackBlitz demo