简体   繁体   中英

Property 'update' and 'quantity' doesn't exist on type '{ }'

I'm watching the tutorial of Mosh Hamedani using the Angular version 6 but the problem is the tutorial version is 4. I'm working on the e-commerce project on AddToCart button where the product should increase it's quantity by clicking the button and updated in Firebase using productId and also if I try to add new product then id of that new product should add in AngularFire Database. I've error in the last line of item.update() and item.quantity. Please go through the code and suggest me better solution. Thanks in advance

Here is the code.

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});
    })
  }
}

Expected results are that after clicking on Add To cart button, the product quantity must be updated in firebase

Have a look at my other files(for reference) 1. home.component.html (Here is the button when clicked goes to .ts file as shown below)

<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 (the click event defined here)
addToCart(product:Product) {
     this.cartService.addToCart(product);
   }

and the last file 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});
    })
  } 

Here are the error images: 1. The error is back 类型{}上不存在属性数量 2. Now when I modify the above code of addToCart(product: Product) which is as:

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});
     }   
    });
  }

I get following error: 项目编译成功,但是单击按钮后未定义键

This is all I have... Please see the errors again and suggest a better solution... Thanks in advance

You use the update method on the value you get from the database. You have to use the update method on a database object.

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

I could not test it, let me know if it works.

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});
    })
 }

Is your products.component.ts file looking like this?

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();
    }
}

Here look at the ngOnInit() function. Before .subscribe() you have to write .valueChanges()

That means you have to write

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 });
        }
    });
}

I think it will work. Please inform me it works or not.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM