Harish Kollipara
Harish Kollipara

Reputation: 31

angular view is not updating after component value gets changed

Hi I have cart which has three views. Top header view, Middle Products view, Bottom footer view. Each view has its own components.

In header view, I have cart icon next to that I want to show the cart products count.

I have two scenarios:

Scenaio1: Assume Cart contains two products, when the page loads all the three views get loaded as per their individual components data. In this scenario Cart count is showing 2 as expectd.

Scenario2: No I'm clicking add to cart option for the one of the product available in the middle view. product added to the data correctly I need to update the cart count in the header view, So I'm calling the one function available in the header component from the middle view and adding one to the actual cart count variable which is available in the header component. when I put logs cart count is printing correctly but header View is not getting updated. Can someone help me how to get updated value.

Source Code:

Header component:

...............
........
noOfItems:any = 2;
update updateCartCount(){
  this.noOfItems = this.noOfItems + 1;
}
........
............

Header View (HTML File):

<li class=""><a routerLink="/my-cart" alt="Wishlist"
                                            title="Wishlist"><i class="fa fa-shopping-cart"></i>**{{noOfItems}}**</a></li>

Middle Component

import {headerComponent} from './../../HeaderFooter/components/header.component';


export class DashboardRole implements AfterViewInit {

headerComp = new headerComponent();

  addProductToCart(){
      .....logic to save product details to database....
      this.headerComp.updateCartCount();
  }
}

Upvotes: 0

Views: 1521

Answers (1)

wickdninja
wickdninja

Reputation: 1039

This seems like a good fit for an observable data service

interface Item {
    id: number;
    name:string;
    price:number;
}

@Injectable()
export class Cart {
    private _items: BehaviorSubject<List<Item>> = new BehaviorSubject(List());

    public items: Observable<Item[]> = this._items.asObservable();

    addItem(newItem:Item):Observable{
         this._items.next(this._items.getValue().push(newItem));
    }
}

Then you can consume the Cart either inside the component like this

@Component({
    selector: 'app-cart-counter',
    template: `
        <div>Count: {{items.length}}</div>
    `
})
export class CartCounterComponent implements OnInit {
    items: Item[];

    constructor(
        private cart: Cart
    ) {}

    ngOnInit(){
        this.cart.items.subscribe(items => this.items = items;)
    }
}

Or use the observable directly in the template like this

@Component({
    selector: 'app-cart-counter',
    template: `
        <div>Count: {{(cart.items | async).length}}</div>
    `
})
export class CartCounterComponent{
    constructor(
        private cart: Cart
    ) {}
}

More information on component interaction can be found in the docs here: https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service

More can be found on the Observable Data Service pattern here: http://blog.angular-university.io/how-to-build-angular2-apps-using-rxjs-observable-data-services-pitfalls-to-avoid/

Upvotes: 1

Related Questions