daniel-d2
11/22/2017 - 9:39 PM

Optimistic state management

Optimistic state management

const Basket = () => {
  let basketState = {
    numberOfItems: 0,
    totalCost: 0
  };

  let subscriptions = [];

  const subscribe = (subscription) => {
    subscriptions = subscriptions.concat(subscription)
  };

  const updateBasketState = (newBasketState) => basketState = newBasketState;

  const callSubscriptions = () => {
    subscriptions.forEach((subscription) => subscription(basketState))
  };

  const setNumberOfItems = (numberOfItems) => {
    const newBasketState = {...basketState, numberOfItems};
    if (!R.equals(basketState, newBasketState)) {
      updateBasketState(newBasketState);
      callSubscriptions()
    }
  };

  const setTotalCost = (totalCost) => {
    const newBasketState = {...basketState, totalCost};
    if (!R.equals(basketState, newBasketState)) {
      updateBasketState(newBasketState);
      callSubscriptions()
    }
  };

  const getNumberOfItems = () => basketState.numberOfItems;

  const getTotalCost = () => basketState.totalCost;

  return {
    subscribe,
    setNumberOfItems,
    setTotalCost,
    callSubscriptions,
    getNumberOfItems,
    getTotalCost
  }
};

const updateDom = (basket) => {
  $('#number-of-items').html(basket.getNumberOfItems());
  $('#total-cost').html(basket.getTotalCost());
};

$(document).ready(() => {
  const basket = Basket();

  updateDom(basket);

  basket.subscribe((newBasketState) => {
    console.log('The state was changed', newBasketState);
    updateDom(basket);
  });

  $('#number-of-items-setter').on('click', () => basket.setNumberOfItems(20));
  $('#total-cost-setter').on('click', () => basket.setTotalCost(200));
});
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Optimistic State Management</title>
</head>
<body>

<p>Number of items: <span id="number-of-items"></span></p>
<p>Total Cost: <span id="total-cost"></span></p>

<button id="number-of-items-setter">Set number of items</button>
<button id="total-cost-setter">Set total cost</button>

<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.js"></script>
<script src="pub-sub.js"></script>
</body>
</html>