Koala Smartblock docs

This section is not public yet. Enter the password you received from Koala.

Skip to main content

Events and basket state

The widget keeps your page informed through events. You register callbacks, the widget calls them as things happen, and you use them to keep your own UI in sync (for example a running total or an order summary). It also writes the current basket to a shared place for you to read.

The events surface​

Koala events live on window.CTStore.koala.events. Each event listener is an array of callbacks, and each callback receives (status, data), plus a third argument you can ignore. Register them before the loader script runs, as part of the koala namespace, or add them to its arrays later: the widget reads the arrays when it fires (see Widget loading for the one ordering rule).

There are five events; when each fires and the data each carries are documented in the reference page Events.

The widget events flow

Registering handlers​

Register every handler on window.CTStore.koala.events:

window.CTStore = {
dataSource: {
/* ... */
},
koala: {
events: {
onReady: [(status) => {}],
onAvail: [(status, data) => {}],
onBundle: [(status, data) => {}],
onBasket: [(status, data) => {}],
onError: [(status, data) => console.error(data.message)],
},
},
};

One bundle event per state change​

Each bundle is undecided, selected, or declined, and onBundle fires once for every bundle whose state changes, whatever control the traveller used. A bundle leaving a state fires first (UNSELECT, UNDECLINE), then a bundle entering one (SELECT, DECLINE). So declining a selected bundle fires UNSELECT then DECLINE; a global "No thanks" fires DECLINE for every bundle and, when turned off, UNDECLINE for every bundle; selecting a bundle while all are declined fires UNDECLINE for each, then SELECT. The state the widget starts with, a partner default or a selection restored after a reload, fires no onBundle: read it from onBasket. UNDECLINE can therefore arrive without a preceding DECLINE when the partner starts with everything declined.

When nothing will render​

onAvail SUCCESS carries a count of the priced bundles the widget will render. When it is 0, the quote succeeded but no bundle is sellable for this trip (the rejection reasons are in response.data.quotes), and the widget renders nothing. It also prepares no request: basketPayload stays undefined, so there is nothing to send after the booking. Treat that the same way as a quote failure and collapse any space your page reserved:

window.CTStore.koala.events.onAvail = [
(status, data) => {
if (status === 'ERROR' || data.count === 0) {
hideProtectionSection(); // your own function
}
},
];

On koala.events, the onBasket data is the Koala basket itself (read it directly):

window.CTStore.koala.events.onBasket = [
(status, data) => {
const { selectedBundles, declinedBundles } = data;
updateOrderSummary(selectedBundles); // your own function
},
];
note

On pages that also run the CarTrawler car-rental Smartblock, the basket change is additionally mirrored on the shared window.CTStore.events bus, under a koala key. How the two event surfaces coexist is covered in Alongside the car-rental Smartblock.

Basket state on window.CTStore.koala​

Alongside the onBasket event, the widget writes the latest basket to window.CTStore.koala.basketPayload, so you can read the current state at any time without waiting for an event. Its shape is documented in the reference page Events. Its book property is what your application sends after the booking to create the subscription or delete the quote (see Creating the subscription).

The selection survives a page reload​

Booking pages reload, sometimes on their own. The widget keeps the traveller's selection for one hour in the browser's local storage, so a reload does not start empty. On the next load it quotes the trip again, reselects the stored bundles that are still priced (a bundle the new quote did not price is silently dropped), rebuilds the prepared request against the new quote, and fires onBasket once so your page can rebuild its order summary. No onBundle event fires for a restored bundle.

The stored selection is scoped to your partner, the placement (dataSource.custom.context) and the trip: a choice made at checkout never resurfaces on the confirmation page, and two tabs open on different trips do not interfere. A traveller who cleared their selection starts from your configured defaults again, and so does one who comes back after the hour. Only bundle ids are stored, nothing about the trip or the traveller.

If window.CTStore.koala.basketPayload is still present when the widget loads, for example in a single-page application that keeps the global object across routes, that basket takes precedence over the stored selection and is restored without firing onBasket.