Property 'update' does not exist on type 'Observable<{}>'. Firebase 5 AngularFire2 5

本秂侑毒 提交于 2019-12-23 12:29:08

问题


I am trying to create/update shopping-cart in firebase. I am using a service that has functions that add the localStorage ID to firebase and It add's the quantity in shopping-cart if the product already exist otherwise it created new one. The error occurred in console TypeError: Cannot read property 'quantity' of null and I also got error on compilation in shopping-cart service.ts:

  1. Property 'update' does not exist on type 'Observable<{}>'.
  2. Property 'quantity' does not exist on type '{}'

The following image demonstrate what I'm trying to get in firebase:

shopping-cart.service.ts

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

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

  constructor(private db: AngularFireDatabase) { }

  private create(){
    console.log('shoping service')
   return this.db.list('/shopping-carts').push({
      dateCreated: new Date().getTime()
    });
  }

 private getCart(cartId: string){
   return this.db.object('/shoping-carts/'+ cartId);
 }

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

    if(cartId) return cartId;

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

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

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

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

shoppng-cart.service.ts (relevant part of document)

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

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


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

product-card.component.ts

import { ShoppingCartService } from './../shopping-cart.service';
import { Product } from './../models/product';
import { Component, OnInit, Input } from '@angular/core';

@Component({
  selector: 'product-card',
  templateUrl: './product-card.component.html',
  styleUrls: ['./product-card.component.css']
})
export class ProductCardComponent implements OnInit {

  @Input('product') product;
  @Input('show-actions') showActions = true;
  constructor(private cartService:ShoppingCartService) { }

  addToCart(product:Product){
   this.cartService.addToCart(product);
  }

  ngOnInit() {
  }

}

product-card.component.html

<div *ngIf="product.title" class="card m-auto">
    <img class="card-img-top" [src]="product.imageUrl" *ngIf="product.imageUrl" alt="{{ product.title }}">
    <div class="card-body pb-0">
      <h5 class="card-title">{{product.title}}</h5>
      <p>{{product.price | currency: 'USD'}}</p>
    </div>
    <div  class="card-footer p-0 border-top">
        <button *ngIf="showActions" (click)="addToCart(product)" class="btn btn-primary btn-block">Add to Cart</button>
    </div>
  </div>

product.ts:

export interface Product{
    key:  string;
    title: string;
    price: number;
    category: string;
    imageUrl: string;   
}

回答1:


Error is pretty descriptive observable has no such property. Its because valueChanges() function returns an observable and it has only data in it. But AngularFireObject has update function and you need to use it. So you need to modify your code like:

private getItem(cartId: string, productId: string): {
  return this.db.object<any>('/shopping-carts/' + cartId + '/items/' + productId);
}

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

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



回答2:


After lot of searching and debugging also part of Yevgen answer I have modified my code to get rid of ERROR TypeError: Cannot read property 'quantity' of null. If I use valueChanges it makes error on new cart addition. So I changed to snapshotChanges and put some logic of it's existence and working fine now. If someone still update my answer your're most welcome.

private getItem(cartId:string, productId:string) {
  return this.db.object < any > ('/shopping-carts/' + cartId + '/items/' + productId); 
}

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

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


来源:https://stackoverflow.com/questions/52474408/property-update-does-not-exist-on-type-observable-firebase-5-angularfir

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!