Félix Debon
Félix Debon

Reputation: 86

Angular subscribe to a service: subscribe is not a function

I'm following the official Angular tutorial and I'm on this step: https://angular.io/start/data#display-the-cart-items They show how to use a service in a component.

It's not in the tutorial but I'm trying to display the number of product present in the cart inside the TopBarComponent.

My service cart.service.ts :

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class CartService {
  items = [];

  addToCart(product) {
    this.items.push(product);
    console.log(this.items);
  }

  getItems() {
    return this.items;
  }

  clearCart() {
    this.items = [];
    return this.items;
  }

}

My component top-bar.component.ts:

import { Component, OnInit } from '@angular/core';
import { CartService } from '../cart.service';//Set up the 

@Component({
  selector: 'app-top-bar',
  templateUrl: './top-bar.component.html',
  styleUrls: ['./top-bar.component.css']
})
export class TopBarComponent implements OnInit {
  public numberItems = 0;
  constructor(
    private cartService: CartService,//Inject the cart service
  ) { 

  }

  ngOnInit() {
    this.cartService.getItems.subscribe((items) => {
       this.numberItems = items.length;
       alert(this.numberItems);
    })
  }

}

My template top-bar.component.html

<a [routerLink]="['/']">
  <h1>My Store</h1>
</a>

<a [routerLink]="['/cart']" class="button fancy-button">
{{numberItems}}
<i class="material-icons">shopping_cart</i>Checkout</a>

I got an error: this.cartService.getItems.subscribe is not a function

And of course the number of product doesn't change if I add a product in the cart. Should I use an Obsevable on getItems ?

Any ideas what I am doing wrong?

Upvotes: 1

Views: 5041

Answers (2)

In your Service, you can add an event emitter, that will emit the length each time something added to the cart.

In CartService Do like this

import { Injectable, EventEmitter } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class RecipesService {
  cartQty = new EventEmitter<number>();
  items = [];
  constructor() { }

 addToCart(product) {
    this.items.push(product);
    this.cartQty.emit(this.items.length);
  }

  getItems() {
    return this.items;
  }

  clearCart() {
    this.items = [];
    this.cartQty.emit(this.items.length);
    return this.items;
  }

  getCartQty() {
    return this.cartQty;
  }
}

In Topbar component.ts

import { Component, Input, OnInit } from '@angular/core';
import { RecipesService } from './app.service';

@Component({
  selector: 'hello',
  template: `<h1>cart {{qty}}!</h1>`,
  styles: [`h1 { font-family: Lato; }`]
})
export class HelloComponent implements OnInit {
  constructor(private recipesService:RecipesService) {};
  qty: number;
  @Input() name: string;

  ngOnInit() {
    this.recipesService.getCartQty().subscribe(res => {
      this.qty = res;
    })
  }
}

Working Solution

Upvotes: 1

Adrita Sharma
Adrita Sharma

Reputation: 22203

Subscribe works with Observables.

Try like this:

getItems(): Observable<any> {
  return of(this.items);
}

else just do,

this.numberItems = this.cartService.getItems().length

Upvotes: 3

Related Questions