The shopping cart in Litium Accelerator is built as a React component. It displays the CartViewModel, built by the CartViewModelBuilder. You can also build the shopping cart in another library or framework. To understand how this works, let's take a look at the components that are needed:
Back end:
- CartController: a WebAPI controller to communicate with the React component.
- CartViewModelBuilder: a model builder that is part of the Business Logic Layer (BLL). Read more about the BLL here.
- RequestModelAccessor: to access the cart.
- ClientContextViewModelBuilder: to build the client context view model, which contains the cart's data. This client context is returned to the client via the DOM content, so that the cart component can use it. That is also covered in an article about the architecture of Litium Accelerator.
Front end:
- MiniCart.js: the mini cart presentational component that is shown in the top-right corner of every page.
- Cart.js: the cart presentational component that is shown on the checkout page.
- MiniCart.container.js: the Mini cart container component that connects the presentational component MiniCart.js to Redux.
- Checkout.container.js: the checkout container component that connects the presentational component Cart.js to Redux.
- Cart.action.js: the Redux action for the cart.
- Cart.reducer.js: the Redux reducer for the cart.
For more details about the difference between presentational and container components, please check this page.
Display the mini cart
The mini cart is shown on all pages, where it always stays at the top-right corner. Here is what happens when a page, for example the start page, is loaded:
- _Layout.cshtml is used to render the page. It invokes the Index action of the ClientContextController, which calls ClientContextViewModelBuilder to build the CartViewModel, and renders the partial view ClientContext.cshtml.

- ClientContext.cshtml renders a script block that sets the cart data for the preloadState. Here is the source of the start page, where we can see the output script block:

- Header.cshtml renders an empty DIV tag with miniCart as the id

Here it is the server that builds the CartViewModel, sets it as the value of window.__litium.preloadState.cart and renders an empty DIV tag with miniCart as the id.
This is what happens when the browser renders the page:
- index.js is executed first. It constructs Redux's store with the preloadState, so that we have the cart's data in the state, ready to use.

- index.js also finds the DIV tag with miniCart as the id, and boots up the MiniCartContainer component.

- MiniCartContainer connects the MiniCart component with Redux's store. The MiniCart component renders the mini cart with the data that the cart has in Redux's store.
Manipulating the shopping cart
The shopping cart can be updated by adding more items to it, by changing the quantity or by removing existing items. Please refer to the Buy button article to understand how it works and updates the cart.
There is a section in the checkout page where detailed information of a cart is displayed, and where a visitor can change the quantity or remove items. This area is rendered by Cart.js. Actions update, coming from Cart.action.js, is called in that case.
export const update = (rowSystemId, quantity) => (dispatch) => {
return put(`/api/cart/update`, { rowSystemId, quantity })
.then(response => response.json())
.then(cart => dispatch(receive(cart)))
.catch(ex => dispatch(catchError(ex, error => loadError(error))))
;
}
The first parameter is the SystemId of the order row, to update or to delete. The second parameter is the quantity. If it is zero, the item will be removed from the cart.
The update action of CartController.cs would then be invoked. It returns the new cart model, so that the client components can update their data to show the new information.
How the Cart object is stored
The Cart object is stored in the HttpContext, under the key ShoppingCartKey. However, we should not access the HttpContext to get the cart. The best way to access it is via RequestModelAccessor, which is located under Litium.Accelerator.Routing namespace.
First, inject the RequestModelAccessor via the constructor:
public class SampleController : ApiControllerBase
{
private readonly RequestModelAccessor _requestModelAccessor;
public SampleController(RequestModelAccessor requestModelAccessor)
{
_requestModelAccessor = requestModelAccessor;
}
}
Then access the Cart object property:
_requestModelAccessor.RequestModel.Cart
Cart total
Information regarding the grand total, the discount amount, delivery cost or other fee is stored in the OrderCarrier of the Cart object. Please check CartViewModelBuilder to see how this information is populated to the CartViewModel.