Search code examples
angulardata-bindingngonchanges

OnChanges won't detect the changes


I am creating a simple app. And I pass an array to the child component. When I remove an item from the array, ngOnChanges won't detect the changes unless I refresh the page.

I can log the changes only once at the first page load but not when the array changes.

Thanks in advance for your time.

Parent Component:

<div class="wrapper">
  <div class="cart-container">
    <h1>In Cart</h1>
    <mat-card class="list-item" *ngFor="let x of shoppingCart">
      <div class="list-title">{{ x.title }}</div>
      <button color="warn" mat-icon-button (click)="deleteFromCart(x)">
        <mat-icon class="material-icons">clear</mat-icon>
      </button>
    </mat-card>
    <app-calculator [shoppingCart]="shoppingCart"></app-calculator>
  </div>
  <hr />
  <app-favourites></app-favourites>
</div>
import { Component, Input, OnInit } from '@angular/core';
import { ProductModel } from 'src/app/models/product/product-model';
import { CartService } from 'src/app/services/cart.service';

@Component({
  selector: 'app-shopping-cart',
  templateUrl: './shopping-cart.component.html',
  styleUrls: ['./shopping-cart.component.scss']
})
export class ShoppingCartComponent implements OnInit {
  public shoppingCart: ProductModel[] = [];

  constructor(
    private cartService: CartService
  ) {}

  ngOnInit(): void {
    this.getItems();
  }

  getItems(): void {
    this.shoppingCart = this.cartService.getItems();
  }

  deleteFromCart(item: ProductModel): void {
    this.shoppingCart = this.cartService.deleteItemFromCart(item);
  }
}

Child Component:

import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';
import { ProductModel } from 'src/app/models/product/product-model';

@Component({
  selector: 'app-calculator',
  templateUrl: './calculator.component.html',
  styleUrls: ['./calculator.component.scss']
})
export class CalculatorComponent implements OnChanges {
  @Input() shoppingCart: ProductModel[] = [];
  public total: number = 0;

  constructor() {}

  ngOnChanges(changes: SimpleChanges): void {
    console.log(changes)
  }
}

Solution

  • Try this:

      deleteFromCart(item: ProductModel): void {
        this.shoppingCart = [...this.cartService.deleteItemFromCart(item)];
      }
    

    But it's more correct that cartService.deleteItemFromCart returns a copy of the array of items without the item removed, rather than returning the same array from which the item was removed.