jQuery Pub/Sub Pattern

An example of the jQuery Pub/Sub implementation

by Larry D'Almeida

HTML

<div id="loader" style="display:none">Processing your request...</div>

<!-- Cart actions -->
<p id="add-to-cart-status"></p>
<button id="add-to-cart" data-item-sku="123" data-item-qty="1">Add</button>
<div id="cart-count">0</div>

JavaScript

/* jQuery Tiny Pub/Sub - v0.7 - 10/27/2011
 * http://benalman.com/
 * Copyright (c) 2011 "Cowboy" Ben Alman; Licensed MIT, GPL */

(function($) {

  var o = $({});

  $.subscribe = function() {
    o.on.apply(o, arguments);
  };

  $.unsubscribe = function() {
    o.off.apply(o, arguments);
  };

  $.publish = function() {
    o.trigger.apply(o, arguments);
  };

}(jQuery));

/********************************************************
	APP
********************************************************/
$(document).on('click', '#add-to-cart', handleAddToCart);
$.subscribe('product-loader/toggle', toggleLoader);
$.subscribe('add-to-cart/success', handleAddToCartSuccess);
$.subscribe('add-to-cart/error', handleAddToCartError);
$.subscribe('add-to-cart/error', alertError);

function handleAddToCart(event) {
  const $this = $(this);
  const attributes = getProductAttributes($this);
  addItemToCart(attributes);
}

function getProductAttributes($button) {
  return {
    skuId: $button.data('item-sku'),
    quantity: $button.data('item-qty')
  };
}

function addItemToCart(attributes) {
  $.publish('product-loader/toggle', true);
	
  //simulate AJAX request with setTimeout
  setTimeout(function() {
    var r = Math.random();
    r >= 0.5 ? $.publish('add-to-cart/success', attributes):
    $.publish('add-to-cart/error', attributes);
    $.publish('product-loader/toggle', false);
  }, 1500);
}

function toggleLoader(event, isShow) {
  var style = isShow ? 'block' : 'none';
  $('#loader').css('display', style);
}

function handleAddToCartSuccess(data, textStatus, jqXHR) {
  $('#add-to-cart-status').text('Item added to cart!');
  var cartCount = Number.parseInt(
  	$('#cart-count').text()
  );
  $('#cart-count').text(cartCount + 1);
}

function handleAddToCartError(jqXHR, textStatus, errorThrown) {
  $('#add-to-cart-status').text('This item is currently out of stock.');
}

function alertError(event, attributes) {
	alert('An error occured while addng product: ' + attributes.skuId);
}