← Back to incidents

Angular incident

Cart badge and cart page drift out of sync

The header badge and the cart page stop agreeing because one feature quietly creates a second CartService instance.

Intermediate14 min

Failure signals

The clues you start with

01

The header shows 3 items while the cart page shows 0

02

Refreshing the cart page briefly 'fixes' only one side

03

The feature component has its own CartService provider

Overview

What failed in production?

Start by making the bug legible: what the user saw, why it mattered, and what the product was doing underneath.

Guided simulator

Symptom

A user adds products from the catalog and sees the header badge move to 3, but when they open the cart page it says the cart is empty. Sometimes the cart page then adds an item and the badge still stays at 3.

User impact

Users stop trusting checkout because the app cannot agree on what is actually in the cart.

Environment

Angular storefront. `CartService` uses `providedIn: 'root'`, but the cart feature shell also lists `providers: [CartService]`. The header badge and the cart page both inject the service.

Evidence pack

What you can inspect before answering

Note

Visible mismatch

The header and the cart page can both be open at the same time, and they show different item counts even though they are supposed to share one source of truth.

Log

Runtime clue

A debug log prints two different `CartService` instance ids: one in the app shell and one inside the cart feature.

Snippet

Cart feature shell

@Injectable({ providedIn: 'root' })
export class CartService {
  items: CartItem[] = [];
}

@Component({
  selector: 'app-cart-shell',
  templateUrl: './cart-shell.component.html',
  providers: [CartService]
})
export class CartShellComponent {
  constructor(public cart: CartService) {}
}
Overview