Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Take is not a function : Angular 7 | Observable.take throws runtime error

I am building a shopping cart and I have used a shopping cart service in which I am assigning the quantities to a product/adding a product to the cart. Is there any other way than to use take for getting the first instance of the observable item$ ?

I am importing the take operator correctly yet it keeps giving me runtime error. If I don't use take, then the quantity assigned is some random integer instead of 1.

I am getting the below error on using take() on an observable in the below code :

import { Injectable } from '@angular/core';
import { AngularFireDatabase } from 'angularfire2/database';
import { Product } from '../app/models/product';
import 'rxjs/add/operator/take';//tried this one too
import { take } from 'rxjs-compat/operator/take';

@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);
    item$.take(1).subscribe(item=>{
      if(item.$exists()) item$.update({quantity : item.quantity + 1});
      else item$.set({product : product , quantity : 1 });
    });
  }

}




Error: Uncaught (in promise): TypeError: item$.take is not a function. (In 'item$.take(1)', 'item$.take' is undefined) http://localhost:4200/main.js:1581:35 step@http://localhost:4200/main.js:1534:27 fulfilled@http://localhost:4200/main.js:1506:62 onInvoke@http://localhost:4200/vendor.js:46707:39 run@http://localhost:4200/polyfills.js:2483:49 http://localhost:4200/polyfills.js:3217:37 onInvokeTask@http://localhost:4200/vendor.js:46698:43 runTask@http://localhost:4200/polyfills.js:2533:57 drainMicroTaskQueue@http://localhost:4200/polyfills.js:2940:42 invokeTask@http://localhost:4200/polyfills.js:2845:40 invokeTask@http://localhost:4200/polyfills.js:3885:20 globalZoneAwareCallback@http://localhost:4200/polyfills.js:3911:27
resolvePromise — zone.js:814
(anonymous function) — zone.js:724
fulfilled — products.component.ts:11
onInvoke — core.js:14143
run — zone.js:138
(anonymous function) — zone.js:872
onInvokeTask — core.js:14134
runTask — zone.js:188
drainMicroTaskQueue — zone.js:595
invokeTask — zone.js:500
invokeTask — zone.js:1540
globalZoneAwareCallback — zone.js:1566
like image 555
Prateek Chitransh Avatar asked Dec 04 '18 13:12

Prateek Chitransh


People also ask

How to handle error in observable?

Catch errors in the observable stream Another option to catch errors is to use the CatchError Operator. The CatchError Operators catches the error in the observable stream as and when the error happens. This allows us to retry the failed observable or use a replacement observable.

What is the use of observable in Angular?

Angular makes use of observables as an interface to handle a variety of common asynchronous operations. For example: The HTTP module uses observables to handle AJAX requests and responses. The Router and Forms modules use observables to listen for and respond to user-input events.

What can we use instead of subscribe in Angular?

map instead of . subscribe. Later is mainly used if you want the response updated to the DOM.


1 Answers

2 issues i notice are:

  1. Import - should be : import { take } from 'rxjs/operators';

  2. You should use pipe : in your case:

    item$.pipe(take(1)).subscribe(...)

Read more about it on here

like image 60
dream88 Avatar answered Nov 04 '22 19:11

dream88