Home Manual Reference Source Repository

Entities/Cart

The Cart module provides an interface to the state of the visitor's cart and the cart AJAX API.

For member and method documentation, see the API reference. For event documentation and examples, see below.

Example

The following example shows a simple JS component which keeps track of the number of items in the visitor's cart.

ES6:

import {entities, utils} from '@eastsideco/escshopify';

const cart = new entities.Cart;

export default class CartCounter {
    constructor(element) {
        this._element = element;

        cart.on('update', () => this.render());
        utils.onLoad(() => this.render());
    }

    async render() {
        await cart.ready();

        var count = cart.items.reduce((total, i) => total + i.quantity, 0);
        this._element.innerText = count;
    }
}

Getting Started

Initializing the cart state

Before using the cart module, you should initialize it with the current state of the cart, for example from a binding created in Liquid.

This is done for you automatically if you use SALVO.

ES6:

import {entities, utils} from '@eastsideco/escshopify';

const cart = new entities.Cart;

cartData = { token: '...', items: [ ... ], ... };
cart.initialize(cartData);

Reading the cart

You can access the items in the cart using .items. It's highly recommended to check or wait for the cart entity to be 'ready' before doing this. Async/await makes this quite trivial.

ES6:

import {entities, utils} from '@eastsideco/escshopify';

const cart = new entities.Cart;

// Using async/await
async function printCartItemNames() {
    await cart.ready();
    for (let cart.items as item) {
        console.log(item.title + ' x' + item.quantity);
    }
}

// Using promises
function printCartItemNames() {
    cart.ready().then(() => {
        for (let cart.items as item) {
            console.log(item.title + ' x' + item.quantity);
        }
    });
}

// Checking cart state syncronously
function printCartItemNames() {
    if (cart.isReady) {
        for (let cart.items as item) {
            console.log(item.title + ' x' + item.quantity);
        }
    }
}

Setting cart items and attributes

You can modify the cart items using #addItem, #updateItem, etc. You can modify cart attributes using #setAttribute or #setAttributes.

ES6:

cart.addItem(variantId, 1);
await cart.addItem(variantId, 1);
cart.updateItemById(variantId, 3);
// Setting a line item attribute on each item in the cart:
for (let item, lineNumber of cart.items) {
    cart.updateItem(lineNumber, item.quantity, {
        promotion: 'Added by promotion'
    });
}

Important warning about async

Warning: Most setter methods are asynchronous. Await the promise fulfillment, or be aware that the cart state may not reflect your changes.

Examples:

ES6:

// starting cart attributes: { test: 1 }
cart.setAttribute('test', 2);
console.log(cart.getAttribute('test')); // may still 1?
// starting cart attributes: { test: 1 }
await cart.setAttribute('test', 2);
console.log(cart.getAttribute('test')); // definitely 2
// starting cart attributes: { test: 1 }
cart.setAttribute('test', 2).then(() => {
    console.log(cart.getAttribute('test'); // definitely 2
});

You can use Promise#all to wait for multiple changes to complete:

// Set attributes on all line items and wait until complete
var promises = [];
for (let item, lineNumber of cart.items) {
    promises.push(cart.updateItem(lineNumber, item.quantity, { attribute: 'test' }));
}
console.log(cart.items); // Attributes may or may not be updated?
await Promise.all(promises);
console.log(cart.items); // Attributes are definitely updated

Events

Listen to the following events to track the lifecycle of this entity.

update

The cart was modified.

Object[]    items       - The new state of items in the cart.
String      operation   - 'add', 'item-updated', 'remove', 'init', or 'attribute-updated'
Object|Null item        - Item that was added/updated/removed.

Updating an item to 0 qty is considered a remove.

cart.on('update', (e) => {
    this.cartTotalMinusGiftcards = _.reduce(e.items, (total, item) => {
        return item.gift_card ? total : total + item.line_price;
    }, 0);
});

add

An item has been added.

Object[]    items       - The new state of items in the cart.
Object      item        - Item that was added.

Updating an existing item with higher qty does not fire this event (see item-updated).

cart.on('add', (e) => {
// "Thanks for adding Example Product!"
window.alert('Thanks for adding ' + e.item.product_title + '!');
});

item-updated

An item has been modified.

Object[]    items       - The new state of items in the cart.
Object      item        - Item that was updated (after update).

Adding a new line item does not fire this event (see add).

remove

An item has been removed.

Object[]    items       - The new state of items in the cart.
Object      item        - Item that was removed.

clear

The cart is now empty.

Object[]    oldItems    - Items that were previously in the cart.

This will typically fire when the last item is removed from the cart.