title: Angular component view layer not updating with localStorage changes without refresh
body: <p>I have two components utilizing the same service to get() and set() items to localStorage. One component sets()/'adds' items to localStorage</p>
  
  <pre><code>import { Component, OnInit, Input } from '@angular/core';
  import {Product} from '../product'; 
  import { PRODUCTS } from '../mock-products'; 
  import {CartService} from '../cart.service'; 
  
  @Component({
    selector: 'app-cart-item',
    templateUrl: './cart-item.component.html',
    styleUrls: ['./cart-item.component.css']
  })
  
  export class CartItemComponent implements OnInit {
    @Input() cartItem: Product; 
  
    constructor(private cartService: CartService) { } 
  
    ngOnInit() { }
  
  
    addToCart() {  // adds item to localStorage
  
    this.closeModal();
    alert('item(s) successfully added to cart');
  
  
    const cart = [];
    const currentCart = this.cartService.get();
    if (currentCart != null &amp;&amp; currentCart.length &gt; 0) {
      for (let i = 0; i &lt; currentCart.length; i++) {
        cart.push(currentCart[i]);
      }
    }
  
     cart.push(this.cartItem);
     this.cartService.set(cart);
  
   }
  }
  </code></pre>
  
  <p>and the other component gets() the data from localStorage displaying the data in a table.</p>
  
  <pre><code>import { Component, OnInit, Input, ChangeDetectionStrategy } from 
  '@angular/core';
  import { Product } from '../product'; // data types
  import { PRODUCTS } from '../mock-products'; // database
  import { CartService } from '../cart.service'; // service
  
  @Component({
  selector: 'app-checkout',
  templateUrl: './checkout.component.html',
  styleUrls: ['./checkout.component.css']
   })
  
  
   export class CheckoutComponent implements OnInit {
   shoppingCart: Product[]; 
   @Input() PRODUCTS: Product; 
   constructor(private cartService: CartService) {  this.shoppingCart = 
    this.cartService.get(); }
  
    ngOnInit() {}
  
    checkOut() {
  
    this.shoppingCart = this.cartService.get();
    console.log(this.shoppingCart); // service is working, changes are 
    not being reflected in HTML
  
  
    const span = document.getElementsByClassName('closeModal')[0];
    const modal = document.getElementById('shoppingCart'); // pulls up 
    modal
    modal.style.display = 'block';
     }
  </code></pre>
  
  <p>Within this same component I am able to make changes to localStorage and see realtime changes by running: this.cartService.get() </p>
  
  <pre><code> deleteItem(id, shoppingCart) {
     const newCart = [];
     for (let i = 0; i &lt; shoppingCart.length; i++) {
       if (shoppingCart[i].id !== id) {
         newCart.push(shoppingCart[i]);
       }
     }
  this.cartService.set(newCart);
  this.shoppingCart = this.cartService.get();
   }
  </code></pre>
  
  <p>}</p>
  
  <p>I have console logged and new items are being set() to localStorage, the table just isn't updated with the new data unless refreshed. </p>
  
  <p>Here is the HTML table that isn't updating, it uses *ngFor to loop over 'shoppingCart' and create the table:</p>
  
  <pre><code>&lt;table id="shoppingCartTable" &gt;
      &lt;thead&gt;
      &lt;th&gt; Item &lt;/th&gt;
      &lt;th&gt; &lt;/th&gt;
      &lt;th&gt; &lt;/th&gt;
      &lt;th&gt; Price &lt;/th&gt;
      &lt;th&gt; Quantity &lt;/th&gt;
      &lt;th&gt; Total &lt;/th&gt;
      &lt;th&gt; Delete? &lt;/th&gt;
      &lt;tr *ngFor="let cartItem of this.shoppingCart"&gt;
        &lt;td&gt;{{cartItem.productName}}&lt;/td&gt;
        &lt;td&gt;&lt;img src={{cartItem.img}} /&gt;&lt;/td&gt;
        &lt;td&gt;{{cartItem.description}}&lt;/td&gt;
        &lt;td&gt;${{cartItem.price}}&lt;/td&gt;
        &lt;td&gt;{{cartItem.quantity}}&lt;/td&gt;
        &lt;td&gt;{{cartItem.price * cartItem.quantity}}&lt;/td&gt;
        &lt;td&gt;&lt;button&gt;&lt;img src="./assets/icons/trashcan.png" 
   (click)="deleteItem(cartItem.id, shoppingCart)" /&gt;&lt;/button&gt;&lt;/td&gt;
    &lt;/tr&gt;
      &lt;tr&gt;
       &lt;button id="checkoutBtn"(click)="confirmCheckout()"&gt; Checkout
       &lt;/button&gt;
      &lt;/tr&gt;
  
    &lt;/thead&gt;
  
      &lt;tbody id="tbodyCart"&gt;&lt;/tbody&gt;
    &lt;/table&gt;
  </code></pre>
  
  <p>Here is my service:</p>
  
  <pre><code>import { Injectable } from '@angular/core';
  import { Product } from './product'; // data model
  import { PRODUCTS } from './mock-products'; // database +
  
  @Injectable()
  export class CartService {
  
   constructor() { }
  
   set(shoppingCart: Product[]) { 
     localStorage.setItem('shoppingCart', JSON.stringify(shoppingCart));
    }
   get() {
     return JSON.parse(localStorage.getItem('shoppingCart'));
     }
  
  
   }
  </code></pre>
  
  <p>I have tried using default ChangeDetectionStrategy as well as .OnPush, neither work. I have combed through stackoverflow and read about RxJs observables but haven't been able to apply/am not quite understanding how they work, not even sure that's the answer. How might I get my view layer to respond to changes in localStorage from another component without refreshing? I am new to Angular and would like an Angular solution, but any direction would be helpful!</p>