Alexandr Belov Alexandr Belov - 4 years ago 217
TypeScript Question

Work with a global variable initialized via BehaviorSubject / Angular2

I've got Catalog Component and Cart Service in my app. And I want to add products from my Catalog (array of objects stored in JSON) to the Cart.

So, I need my Cart to be changed dynamically when I add / remove a product.
For that reason I am trying to use { BehaviorSubject }.

Cart Service:

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';


@Injectable()
export class CartService {
public cart = new BehaviorSubject(null);//my globally available Cart

}


Catalog Component:

import { Component, OnInit } from '@angular/core';
import { CatalogService } from './catalog.service';
import { CartService } from '../cart/cart.service';//my globally available Cart imported to the current component

@Component({
selector: 'catalog',
templateUrl: './catalog.component.html',
styleUrls: ['./catalog.component.scss']
})

export class CatalogComponent implements OnInit {
catalog: any;
image: any;
title: string;
description: string;
prod: any;
visible: boolean;

constructor(public catalogService: CatalogService, public cartService: CartService){ }

ngOnInit(){

this.catalogService.getCatalogItems().subscribe(
(data) => this.catalog = data
);
}

toCart(prod){
this.cartService.cart.subscribe((val) => {
console.log(val);
});

this.cartService.cart.push(prod);//I want to add new product to the Cart by this
}

}


But Console throws the following error: enter image description here

So, what should I do to use my Cart globally via BehaviorSubject?

Answer Source

The thing is to stream the whole content of the cart. Thus, we should keep record of all items in the cart at the given moment somewhere. So, each time the item is added to the cart, we dispatch a new stream value via cart$.next() - (not push).

As you can see from the error, BehaviourSubject doesn't have push method.

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';


@Injectable()
export class CartService {
  public cart$ = new BehaviorSubject(null);//my globally available Cart

  private cartAr:Product[] = [];

  public addToCart(prod:Product)
  {
    this.cartAr.push(prod);
    this.cart$.next(this.cartAr);
  }
}


//--------Component----------

import { Component, OnInit } from '@angular/core';
import { CatalogService } from './catalog.service';
import { CartService } from '../cart/cart.service';//my globally available Cart imported to the current component

@Component({
  selector: 'catalog',
  templateUrl: './catalog.component.html',
  styleUrls: ['./catalog.component.scss']
})

export class CatalogComponent implements OnInit { 
  catalog: any;
  image: any;
  title: string;
  description: string;
  prod: any;
  visible: boolean;

constructor(public catalogService: CatalogService, public cartService: CartService){ } 

ngOnInit(){

    this.catalogService.getCatalogItems().subscribe(
        (data) => this.catalog = data
    );
}

  toCart(prod){
      this.cartService.cart$.subscribe((val) => {
            console.log(val); 
      });

    this.cartService.addToCart(prod);
  }

}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download