Ryan Mann
Ryan Mann

Reputation: 53

How to pass an Object from a service to a component

For my website I want to have a cart that you can fill with items. At this moment I am trying to handle this using a service that contains the cart in the form of an object, cart, with functions that can add Items to it and also return the entire cart as a Promise. At the moment I am only able to add items to the cart, but as soon as I try to call getCart() from cart.component.ts, it seems to return a completely empty array unlike the one I would think it was storing. Am I going about this the incorrect way?

cart.service.ts

import {Injectable, EventEmitter} from '@angular/core';
import {Item} from '../../models/item.model';


@Injectable()
export class CartService{
  public cart:Item[] = [];

  constructor(){
  }

  updateCart(){ //just prints the cart size
    console.log('cart size: ' + this.cart.length);
  }
  addItem(item:Item){ //adds an item
    this.cart.push(item);
    this.updateCart();
  }
  checkout(){ //wipes cart
    console.log('cart wiped');
    this.cart = [];
    this.updateCart();
  }


  getCart(): Promise<Item[]>{ //returns the cart
    console.log('getting cart');
    this.updateCart();
    return  Promise.resolve(this.cart);
  }
}

cart.component.ts

    import {Component, OnInit} from '@angular/core';
    import { CartService } from './cart.service';
    import {Item} from '../../models/item.model';


    @Component({
      moduleId: module.id,
      selector: 'sd-cart',
      templateUrl: 'cart.component.html',
      styleUrls: ['cart.component.css'],
      providers: [CartService]
    })

    export class CartComponent implements OnInit{
      public cart: Item[];
      constructor(private cartService:CartService){
        this.cartService.getCart().then(cart => this.cart = cart);
        if (!this.cart)
          console.log('error getting cart');
        else console.log(this.cart.length + ' got cart');
      }
      ngOnInit(){

      }
    }

The problem that I am having is whenever I add Items to the cart from another component it will correctly show the length of the cart from the service (console.log('cart size: ' + this.cart.length);) But as soon as I load the component (triggering the constructor for the component) that same console.log() will print that the array is 0 regardless of how many items I have added to it. Inside of cart.component.ts, the if (!this.cart) console.log('error getting cart'); also triggers from the call: this.cartService.getCart().then(cart => this.cart = cart);. I've looked at many tutorials and even tried somebody else's cart service and haven't had much luck with anything.

Upvotes: 1

Views: 1354

Answers (1)

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 657348

Don't provide CartService everywhere where you inject it. This leads to every component getting its own instance

@Component({
  moduleId: module.id,
  selector: 'sd-cart',
  templateUrl: 'cart.component.html',
  styleUrls: ['cart.component.css'],
  providers: [CartService] // <<<== remove here
})

Only add the service to providers of the @NgModule(). These providers are hoisted in the applications root scope and only one instance will exist and passed to every constructor that depends on it.

Note: Lazy loaded modules have their own root scope and providers are not hoisted to the application root scope.

Upvotes: 1

Related Questions