类型'{}'

时间:2019-05-02 23:46:57

标签: javascript firebase firebase-realtime-database angular6 angularfire

我正在使用Angular版本6观看Mosh Hamedani的教程,但问题是该教程的版本是4。我正在AddToCart按钮上的电子商务项目中,该产品应通过点击来增加其数量按钮,并使用productId在Firebase中更新,并且如果我尝试添加新产品,则该新产品的ID也应添加到AngularFire数据库中。 我在item.update()和item.quantity的最后一行有错误。请仔细阅读代码,并向我提出更好的解决方案。预先感谢

这是代码。

shopping-cart.service.ts

import { Injectable } from '@angular/core';
import { AngularFireDatabase } from 'angularfire2/database';
import { Product } from '../model/product';
import { take } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class ShoppingCartService {

  constructor(private db: AngularFireDatabase, ) { }

  private create() {
   return this.db.list('/shopping-cart').push({
      dateCreated: new Date().getTime()
    })
  }

  private getCart(cartId: String) {
    return this.db.object('/shopping-cart/' + cartId);
  }

  private getItem(cartId:string, productId: String) {
   return this.db.object('/shopping-cart/' + cartId + '/items/' +productId);
  }

 private async getOrCreateCart() {
    let cartId = localStorage.getItem('cartId');

    if (cartId) return cartId;

    let result = await this.create();
    localStorage.setItem('cartId', result.key);
    return result.key;  
  }

  async addToCart(product: Product) {
    let cartId = await this.getOrCreateCart();
    let item$ = this.getItem(cartId, product.key);

    item$.valueChanges().pipe(take(1)).subscribe(item => {
      // I'am getting error in update() and quantity
      item.update({ product: product,quantity: (item.quantity || 0) + 1});
    })
  }
}

预期结果是,单击“添加到购物车”按钮后,必须在Firebase中更新产品数量

看看我的其他文件(供参考) 1. home.component.html(单击该按钮即会转到.ts文件,如下所示)

<div class="card-footer">
    <button (click)="addToCart(product)" style="background: #2980b9; 
             color:white" class="btn btn-block">Add to Cart
    </button>
</div>
  1. home.component.ts(此处定义的click事件)
addToCart(product:Product) {
     this.cartService.addToCart(product);
   }

和最后一个文件 3. shopping-cart.service.ts

private async getOrCreateCart() {
    let cartId = localStorage.getItem('cartId');

    if (cartId) return cartId;

    let result = await this.create();
    localStorage.setItem('cartId', result.key);
    return result.key;  
  }

  async addToCart(product: Product) {
    let cartId = await this.getOrCreateCart();
    let item$ = this.getItem(cartId, product.key);

    item$.valueChanges().pipe(take(1)).subscribe(item => {
      item$.update({ product: product,quantity: (item.quantity || 0) + 1});
    })
  } 

这是错误图像: 1.错误又回来了 Property quantity does not exist on type {} 2.现在,当我修改上述addToCart(product:Product)的代码时:

async addToCart(product: Product) {
    let cartId = await this.getOrCreateCart();
    let item$ = this.getItem(cartId, product.key);

    item$.snapshotChanges().pipe(take(1)).subscribe((item: any) => {
      if(item.key != null) {
        item$.update({ product: product,quantity: (item.quantity || 0) + 1});
      } else {
        item$.set( {product:product, quantity:1});
     }   
    });
  }

我收到以下错误: The project compiles successfully, but key is undefined after clicking the button

这就是我的全部...请再次查看错误并提出更好的解决方案...在此先感谢

2 个答案:

答案 0 :(得分:0)

您对从数据库获得的值使用更新方法。您必须在数据库对象上使用update方法。

https://github.com/angular/angularfire2/blob/master/docs/rtdb/objects.md

我无法测试它,让我知道它是否有效。

async addToCart(product: Product) {
    let cartId = await this.getOrCreateCart();
    let itemRef = this.getItem(cartId, product.key);

    itemRef.valueChanges().pipe(take(1)).subscribe(item => {
      itemRef.update({ product: product,quantity: (item.quantity || 0) + 1});
    })
 }

答案 1 :(得分:0)

您的products.component.ts文件看起来像这样吗?

products.component.ts

import { ShoppingCartService } from './../shopping-cart.service';
import { Product } from './../models/product';
import { ActivatedRoute } from '@angular/router';

import { ProductService } from './../product.service';
import { Component, OnInit, OnDestroy } from '@angular/core';
import { switchMap } from 'rxjs/operators';
import { Subscription } from 'rxjs';
@Component({
    selector: 'app-products',
    templateUrl: './products.component.html',
    styleUrls: [ './products.component.css' ]
})
export class ProductsComponent implements OnInit, OnDestroy {
    products: Product[] = [];
    filteredProducts: Product[] = [];
    category: string;
    cart: any;
    subscription: Subscription;
    constructor(
        route: ActivatedRoute,
        productService: ProductService,
        private shoppingCartService: ShoppingCartService
    ) 
    {
        productService
            .getAll()
            .pipe(
                switchMap((products: Product[]) => {
                    this.products = products;
                    return route.queryParamMap;
                })
            )
            .subscribe((params) => {
                this.category = params.get('category');

                this.filteredProducts = this.category
                    ? this.products.filter((p) => p.category === this.category)
                    : this.products;
            });
    }

    async ngOnInit() {
        this.subscription = (await this.shoppingCartService.getCart())
            .valueChanges()
            .subscribe((cart) => (this.cart = cart));
    }
    ngOnDestroy() {
        this.subscription.unsubscribe();
    }
}

在这里查看ngOnInit()函数。 在.subscribe()之前,您必须编写.valueChanges()

那意味着你必须写

async ngOnInit() {
    this.subscription = (await this.shoppingCartService.getCart())
        .valueChanges()
        .subscribe((cart) => (this.cart = cart));
}

shopping-cart.service.ts

async addToCart(product: Product) {
    let cartId = await this.getOrCreateCart();
    let item$ = this.getItem(cartId, product.key);
    item$.snapshotChanges().pipe(take(1)).subscribe((item) => {
        if (item.payload.exists()) {
            item$.update({ quantity: item.payload.exportVal().quantity + 1 });
        } else {
            item$.set({ product: product, quantity: 1 });
        }
    });
}

我认为它将起作用。请通知我它是否有效。