Blog Post‎ > ‎

Implement a Shopping Cart using Google App Script

posted Mar 29, 2015, 5:18 PM by Julian Zhu   [ updated Apr 4, 2015, 11:07 AM ]

Cloud is now offering more than just Iaas (Infrastructure as a Service) and PaaS (Platform as a Service). It offers SaaS (Software as Service) solution for business, too.

(I am researching Amazon Web Services or AWS -- please stay tuned for another post soon.)

Is it good enough?

Google App Script offers one of the options for application development using Google platform and services.

Advantage:
  • Easy and seamless integration of Google services (GMail, Drive, Documents, etc.)
  • Infrastructure backed by Google
  • Easy scripting language (including server scripting capability) using JavaScript and HTML/CSS.

Disadvantage

  • Like anything else (ok, almost everything), it is fully controlled by Google (should we change that?)


Here is an example of implementing a Shopping Cart using Google App Script

Data Storage & Database

  • We will use Google Drive to store data.
  • We will use Google Document Spreadsheet as our database.

Data Files:

  • Product: we will store all products in one spreadsheet file named "Product".
  • Cart: We will create a temporary cart file to store shopping cart info for each customer. The cart will use a randomly generated name to create a spreadsheet document.
Update: Sine we don’t want to create spreadsheet document until shopper submits the order, also for performance consideration, we don’t want read and write this cart document ever time we need to touch it, we changed the implementation to use CacheService for storing and retrieving shopping cart data while the customer is doing shopping. CacheService provides flexible ways of caching mechanisim for different scenarios, for example public (global) cache or user specific (or private) cache. 


Web Site:
  • We create a Google Site. We will use this site to embed Google App Script (as web application).
  • We will create single page HTML. HTML Get Parameters will be provided to direct pages to different functional logic.


Apps Script:

Google App Script is the core of this implementation.

To get started, Go to the Google Site we create (as owner). Go to "Manage Site". We will first need to create Apps Scripts

This is our first time to Apps Scripts. Let's click the button "Add new script".

Since we are creating and developing web application, Select "Web App" when prompted. Provide a name for this project, for example "Shopping Cart" and go ahead and generate the skeleton of the Apps Script web application.

Four core files are now generated by Google Apps Script:

- Code.gs: Google Script (Server side script file)
- Index.html: User Interface (html file)
- JavaScript.html: JavaScript
- Stylesheet.html:


We will need to focus on Code.gs for server side of programming (scripting) and Index.html (for UI).


Code.gs

This is server side script, and we will implement our data model for domain objects, as well as key business actions here to complete backend transaction logic. 

To understand the overall Google Apps Script architecture, you need to understand how the server and client call back model works. The user interaction with app is control by html of course. These html files contains events and controls captured and provided by client side scripts in JavaScript file. Typically JavaScript is responsible sending user data to server side script function (in Code.js of course)in acyncrounous way, and typicallwe will implement another client side method to call when client receives respose from the server call. 



Data Access

We will implement data access and persistence layer by using Google SpreadsheetApp service. Here is sample code of creating a new Spreadsheet document for a given document name:

// cart_name is the name of the spreadsheet created.
var doc = SpreadsheetApp.create("cart_name");

We will get the document Id and keep track of it:
var docID = doc.getId();

Later, we will need to read data from spreadsheet:

var data = SpreadsheetApp
      .openById(docId)        // open by document ID
      .getActiveSheet()        // get active sheet
      .getDataRange()            // get data range in the sheet
      .getValues();
                // get values (as 2-D array)

Domain Object

We define domain objects (or data types) to use. This is typical JavaScript programming:

// Class: Customer
function Customer(name, phone, address) {
    this.name = name;
    this.phone = phone;
    this.address = address;
}

// Class: Product
function Product(id, name, description, unit, size, price, promo_price, image) {
  this.id = id;
  this.name = name;
  this.description = description;
  this.unit = unit;
  this.size = size;
  this.price = price;
  this.promo_price = promo_price;
  this.image = image;
}


// Class: Order Item in a shopping cart
function OrderItem(product, quantity) {
  this.product = product;
  this.quantity = quantity;
}


// Class: Shopping Cart
// Shopping Cart contains Customer Object and Order Items
function Cart(customer, order_items) {
  this.customer = customer;
  this.order_items = order_items;
}


Action Class

We will implement functions to accept parameters from user action (from HTML web UI). This is typically done by onClick() function defined in HTML form.

Index.html


<input type="button" value="Add to Cart"
      onclick="google.script.run
          .withSuccessHandler(updateCart)
          .addToCart(<?= products[i].id ?>, this.form.quatity.value)" />



<script>

// refresh cart count UI/view
function updateCart(count) {
  alert(count + " items added to cart");
  var div = document.getElementById('cart_details');
   div.innerHTML = 'Cart: ' + count;
}

</script>

Code.gs

/**
 * Add to Cart
 */
function addToCart(product_id, quantity) {
 
  var cart = getCart();
  var items = cart.order_items;
 
  var exists = false;
 
  for(var i=0; i < items.length; i++) {
    if(items[i].product.id == product_id) {
      items[i].quantity += parseInt(quantity);
      exists = true; // this item is already in the car, so let's update the quantity
    }
  }
  if(!exists) {
    var item = new OrderItem(getProduct(product_id), quantity);
    items.push(item);
  }
 
  Logger.log('after: ' + items.length);
  // Now we update the cart
  cart.order_items = items;
 
  saveCart(cart);
 
  return quantity;

}

User Session (in Code.gs)

To store temporary user specific values, use:   

var cache = CacheService.getUserCache();
cache.put("key", "value");

We use this to put dynamic generated cart (associated with this user). For new user without shopping cart, we will generate a cart for this user and keep track of the cart id associated with this user.

Caching

use public cache for common data:

var cache = CacheService.getPublicCache();
cache.put("key", "value");




Comments