0

This question is a follow-up to a previous question posted here -- previous question

I'm attempting to place data into a firebase database (Specifically the realtime database) and I've written a service that will get all of my current products, which would then be used inside of a method to create a shopping cart.

However, my service continues to return back an undefined result though I can get and display products on the view.

I've attempted to place my data into an Interface manually but each time I log to the console I get undefined.

This service method is being used to retrieve the products from the firebase database:

getAll() {
    this.itemRef = this.db.list('/products').snapshotChanges().pipe(
        map(changes => {
            return changes.map(c => ({ key: c.payload.key, ...c.payload.val() }));
        })
    );
    return this.itemRef;
}

The below code snippet displays what I have tried to accomplish inside of my component.

products$: Observable<ProdInterface>;
prodLook: ProdInterface[]

this.products$ = this.productService.getAll();

this.productService.getAll().subscribe(data =>
    this.prodLook = [{
        color_way: data.color_way,
        description: data.description,
        $key: data.key,
        name: data.name,
        photo: data.photo,
        price: data.price,
        qty: data.qty
    }]
)

The goal from the above snippet is to pass products$ into this method:

//product returns undefined
async addToCart(product: ProdInterface, change: number) {
    let cartId = await this.getOrCreateCart();
    debugger
    let item$ = this.getItem(cartId, product.$key);
    item$.snapshotChanges().pipe(take(1)).subscribe(item => {

        if (item.payload.exists()) {
            let quantity = item.payload.exportVal().quantity + change;
            if (quantity === 0) item$.remove();
            else
                item$.update({
                    product: item.payload.exportVal(),
                    quantity: quantity
                });
        } else {
            item$.set({ product: item.payload.exportVal(), quantity: 1 });
        }
    })
}

Edit: HTML used to bind to addToCart

<div *ngIf='products$'>
  <div class="row">
    <div class="col-md-4" *ngFor="let product of products$ | async">
      <mdb-card>
        <!--Card image-->
        <mdb-card-img [src]="product.photo" alt="Card image cap"></mdb-card-img>
        <!--Card content-->
        <mdb-card-body>

          <!--Title-->
          <mdb-card-title>
            <h4>{{product.name}}</h4>
          </mdb-card-title>

          <!--Text-->
          <mdb-card-text> 
            {{product.description}}
          </mdb-card-text>
          <span> 
            <mdb-card-text>{{product.price}}</mdb-card-text>
          </span>

        <button (click)="addToCartProd()" class="btn btn-primary btn-block">Add To Cart</button>
        </mdb-card-body>
      </mdb-card>
    </div>
  </div>
</div>

The addToCartProd method used in tandem with the HTML

  // addToCartProd(){
  //   this.cartService.addToCart(this.products$,1)
  //   console.log(this.products$)
  // }

My goal for this code is to attach addToCart to a button on the view and send the correct product to the database based on it's key. The current implementation sends undefined to the database, which is the cause of confusion because the products display on the page using the same getAll() method.

Thanks

Joel Carter
  • 151
  • 12

1 Answers1

1

You template should pass the product from the *ngFor to the addToCardProd(). You template and method should look like something below.

products.component.html

<div *ngIf='products$'>
  <div class="row">
    <div class="col-md-4" *ngFor="let product of products$ | async">
      <mdb-card>
        ...
        <button (click)="addToCartProd(product)" class="btn btn-primary btn-block">Add To Cart</button>
        </mdb-card-body>
      </mdb-card>
    </div>
  </div>
</div>

products.component.ts

addToCartProd(product: ProdInterface){
  this.cartService.addToCart(product,1)
  console.log(products$)
}
Jason White
  • 5,495
  • 1
  • 21
  • 30
  • Though the code solution works, it's still not yielding the result I'm looking for. Firebase still shows `/shopping-carts/cartId/items/undefined` – Joel Carter Aug 31 '19 at 22:27
  • After some more searching and debugging, I figured out that I wasn't passing my product object to the service which rendered it as `undefined`. After passing it from the view to the service...everything works like a charm!! Thanks! – Joel Carter Aug 31 '19 at 22:41
  • @JoelCarter glad you got it figure out. – Jason White Aug 31 '19 at 22:45
  • 1
    Couldn't have done it without ya. consider this a team effort :) – Joel Carter Aug 31 '19 at 22:51