FreshHaze
FreshHaze

Reputation: 33

Angular 2 edit cart total after remove a product

i'm stucked on a problem and i don't know how to get out of it. I have two component sibiling:

One that show a list of products with a button for each product that delete from the cart the single product with a POST call at one REST API.

And another component that simple call a REST API for get the totals of the cart and show it.

The problem is that when i delete correctly the item from the cart, obviously the cart total doesn't update itself.

So, i've searched on the communities and i think that there are two different solutions:

I've tried using the first option, but without success, i tried also with @input and @Output but i don't think that i really understand how to use it between two components that aren't Parent > Child or opposite.

What i need is to call the function GetTotals inside the CARTTOTAL.COMPONENT from the CARTITEMS.COMPONENT for updating the prices.

I've tried to inject the same service in both components and call the function from the first one, but seems doesn't work.

Here the code:

cartitems.component.ts

import { Component, OnInit, Inject, Output } from '@angular/core';

import { ManageGuestCartService } from '../manageCartServices/addtoguestcart.service';
//import { CarttotalComponent } from '../carttotal/carttotal.component';

// Service for guest total cart
import { TotalguestcartService } from '../manageCartServices/totalguestcart.service';


@Component({
  selector: 'app-cartitems',
  templateUrl: './cartitems.component.html',
  styleUrls: ['./cartitems.component.css'],
  providers: [ManageGuestCartService, TotalguestcartService]
})

export class CartitemsComponent implements OnInit {

 itemofcart:any[];

  constructor(private _guestcartservice: ManageGuestCartService, private _totalguestcart: TotalguestcartService) { }

  ngOnInit() {
    this.listCartItems();
  }

  listCartItems() {

    return this._guestcartservice.getCartDetails()
        .subscribe(data => {
            this.itemofcart = data;
            //console.log(this.itemofcart); 
        },
      (err) => {
        //alert('vuoto'); 
      });

  }


  removeProductFromCart(itemid) {
      return this._guestcartservice.deleteProductFromCart(itemid)
      .subscribe(data => {
      //  this.itemofcart = data;
       // console.log(this.itemofcart); 
       this.listCartItems();
       this._totalguestcart.getTotals();
      },
      (err) => {
        alert('errore');
      });
  }

}

carttotals.component.ts

import { Component, OnInit, Input} from '@angular/core';

// Service for guest total cart
import { TotalguestcartService } from '../manageCartServices/totalguestcart.service';

@Component({
  selector: 'app-carttotal',
  templateUrl: './carttotal.component.html',
  styleUrls: ['./carttotal.component.css'],
  providers: [TotalguestcartService]
})
export class CarttotalComponent implements OnInit {

  constructor(private _totalguestcart: TotalguestcartService) { }

   totals:any[];

  ngOnInit() {
    this.retrieveTotals();
  }

  retrieveTotals() {
    return this._totalguestcart.getTotals()
    .subscribe(data => {
        this.totals = data;
        console.log(this.totals);
        },
      (err) => {
        alert(err); 
      });
  }

} 

totalguestcart.service.ts

import { Injectable } from '@angular/core';
import { Http, Headers, RequestOptions} from '@angular/http';

@Injectable()
export class TotalguestcartService {

  constructor(public http: Http) { }



    public getTotals() {
        let cartid;
                cartid = localStorage.getItem("guestCartId");

                let contentHeaders = new Headers();
                contentHeaders.append('Accept', 'application/json');
                contentHeaders.append('Content-Type', 'application/json');

                return this.http.get(URL, { headers: contentHeaders})
                //.map(res => res.json())
                  .map((res) => {
                        if(res.status == 404) {
                          return res.status;
                        } else {
                          return res.json();
                        }
                    });
    }

}

Can someone give me the correct way to find a solution to this issue? all the feeds are accepted :)

Thanks in advance!

Upvotes: 1

Views: 1825

Answers (2)

AVJT82
AVJT82

Reputation: 73367

As mentioned, you need to mark your providers in the module, so that you share the same service between your components.

Shared Service would be best here. From my understanding you want to fire an event in the carttotals component, when deleting an item in the cartitems component.

Well we can set up Observable which will fire that event. So in your totalguestcart service add this:

private fireEvent = new Subject<boolean>();

event = this.fireEvent.asObservable();

emitEvent(bool: boolean) {
  this.fireEvent.next(bool);
}

Here we are just using boolean values, as you do not need to pass any specific values, but only fire an event.

Then when you are performing the deletion, let's notify the other component, which subscribes to this, that the method should be fired.

removeProductFromCart(itemid) {
  return this._guestcartservice.deleteProductFromCart(itemid)
    .subscribe(data => {
      this.itemofcart = data;
      this.listCartItems();
      this._totalguestcart.emitEvent(true); // add this!! 
    },
    (err) => {
      alert('error');
    });
 }

And in your cart totals, subscribe to this in your constructor, and execute the getTotals method:

constructor(private _totalguestcart: TotalguestcartService) { 
  _totalguestcart.event.subscribe(res => {
      this.retrieveTotals();
  })
}

this.retrieveTotals will then be fired each time you are deleting an item. Of course this can be used in other methods as well, like adding and updating (if you need it).

Hope this helps! :)

Upvotes: 2

Myonara
Myonara

Reputation: 1207

Throw out the service TotalguestcartService out of the providers of your components and put it into the providers of the app-module: What is happening: each component is getting a local copy of the service, so they cannot exchange information, as there are TWO services injected. Putting it global (app.module) provides it for every component as long as the component doesn't do an own provider.

Upvotes: 1

Related Questions