Kobe Forrosuelo
Kobe Forrosuelo

Reputation: 233

Property 'take, update, set' does not exist on type 'Observable<{}>'

I tried to follow a tutorial about Angular + Firebase but the version of the tutorial was angular4 and my angular version is 6 also the version of my Firebase and AngularFire2 is also higher than the tutorial which is the latest version right now.

I got this error

Error

This is my source code

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

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

  constructor(private db: AngularFireDatabase) { }

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

  private getCart(cartId: string) {
    return this.db.object('/shopping-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;
  }

  async addToCart(product: Product) {
    let cartId = await this.getOrCreateCartId();
    let item$ = this.db.object('/shopping-carts/' + cartId + '/items' + product.key).valueChanges();
    item$.take(1).subscribe(item => {
      if (item.$exists()) {
        item$.update({ quantity: item.quantity + 1});
      } else {
        item$.set({ product: product, quantity: 1});
      }
    });

  }
}

Upvotes: 1

Views: 3153

Answers (4)

StepUp
StepUp

Reputation: 38094

This is my way of rewritten code:

async addToCart(product: Product) {
    const cartId = await this.getOrCreateCartId();
    const item$ = this.db.object('/shopping-carts/' + cartId + '/items/' + product.id);

    item$.valueChanges()
    .take(1)
    .subscribe(item => {
      if (item) {
        item$.update({quantity: item['quantity'] + 1});
      } else {
        item$.set({ product, quantity: 1 });
      }
    });
  }

Upvotes: 1

Himanshu Patni
Himanshu Patni

Reputation: 195

async addToCart(product) {

  let cartId = await this.getOrCreateCartId();

  let item$: Observable<any> = this.db.object('/shopping-carts/' + cartId +'/items/' + product.key).valueChanges();

  let item$$ = this.db.object('/shopping-carts/' + cartId + '/items/' + product.key);

  item$.take(1).subscribe( item => {
    if( item === null ) {
      item$$.set({product: product, quantity: 1});
      console.log('adding new product to cart');
    }else{
      item$$.update({quantity: item.quantity + 1});
      console.log('updating exisiting product ');``
    }
  });

Upvotes: 1

Faouzi
Faouzi

Reputation: 1019

I've been stuck in the same problem, and I found a work around.

You can not call set methode inside the subscribe method since item$ it of type observable. so I created an other object item$$ of type AngularFireObject<{}>, that I can use inside the subscribe method and update/set the product.

For the .$exists() method I think it's no longer exists, so i checked if the value of item is null, rather than checking if it exists..

Here's my code for the addToCart(p) function:

async addToCart(product) {
  let cartId = await this.getOrCreateCartId();
  let item$: Observable<any> = this.db.object('/shopping-carts/' + cartId + '/items/' + product.key).valueChanges();
  let item$$ = this.db.object('/shopping-carts/' + cartId + '/items/' + product.key);
  item$.take(1).subscribe( item => {
     if( item === null ) {
        item$$.set({product: product, quantity: 1});
        console.log('adding new product to cart');
    }else{
        item$$.update({quantity: item.quantity + 1});
        console.log('updating exisiting product ');
   }
});

Hope this helps

Upvotes: 0

Tim Martens
Tim Martens

Reputation: 1534

In rxjs 6, methods are chained with the pipe operator. You need to use the pipe() operator like so:

async addToCart(product: any) {
    const cartId = await this.getOrCreateCartId();
    const item$ = this.db.object('/shopping-carts/' + cartId + '/items' + product.key).valueChanges();
    item$.pipe(take(1)).subscribe(item => {
        ...
    });
}

Upvotes: 2

Related Questions