Spartacus is an Angular based storefront for the SAP Commerce Cloud product. The calls to backend Commerce Cloud is made via OCC (REST). Spartacus is also a Single Page Application (SPA), Progressive Web Application (PWA). Spartacus has various features like Anonymous Consent, Assisted Service Module, Cancellations & Returns, Consignment Tracking, Coupons, I18n, Wish List etc. Spartacus is published as libraries, which are published bi-weekly.
The system landscape of a Commerce Cloud solution is made up of various systems, which are typically orchestrated on various application layers, including the front end. Spartacus connects to SAP Commerce Cloud APIs by default, and the underlying framework can be used to work with other systems using what is called as “Connectors”. The following diagram depicts a broad architecture of Spartacus:
As seen above there are 4 major layers:
-
- UI Component: Spartacus uses Angular. In Angular, UI is logically organized into many UI components. The UI components observe data provided by the facade layer.
-
- Façade: As the name suggests, main purpose of the Façade layer is to hide the complexity of the underlying in-memory data store.
-
- NgRx (In-memory Store): NgRx is the UI “State Management” Tool. This is useful for a complex UI framework like Spartacus.
-
- Connector: This is called be “Effects” of NgRx store, to interact with the backend SAP Commerce Cloud system. The connector, delegates control to Adapter, which then calls Converters.
-
- Adapter: The adapter layer is responsible for loading and submitting data to a source system.
-
- Converter: It is used to convert the data from backend to UI and vice versa. There are two types:
-
- Normalize: Converts data from backend to UI.
-
- Serialize: Converts data from UI to backend.
-
- Converter: It is used to convert the data from backend to UI and vice versa. There are two types:
-
- Connector: This is called be “Effects” of NgRx store, to interact with the backend SAP Commerce Cloud system. The connector, delegates control to Adapter, which then calls Converters.
Let us take a sample requirement to make some new feature development into the framework. In the storefront, “My Account -> Payment Details”, the billing address should be displayed as highlighted by the red coloured rectangle. This address is set during the shopping cart checkout.
Now how do we go about achieving this technically? As mentioned above, Spartacus is built using Angular framework, where you have UI component. So we have to find the right component for the Payment component.
1.The relevant component is “projects/storefrontlib/src/shared/components/card/card.component.ts”. Since we need additional information on the card, let use create an “Array<string>” with name “additionalInfo” in the interface “Card“:
export interface Card {
header?: string;
title?: string;
textBold?: string;
text?: Array<string>;
img?: string;
actions?: Array<CardAction | CardLinkAction>;
deleteMsg?: string;
additionalInfo?: Array<string>;
}
2. Now, we have a placeholder to display the billing address. But this will be visible only if it is rendered by the UI Component’s HTML. That is “projects/storefrontlib/src/shared/components/card/card.component.html”. Since, “Card.additionalInfo” is “Array<string>”, we have to loop over each item to display its entire content:
<!– Additional Information (e.g., Shipping/Billing Address for Credit Card) –>
<div class=”cx-card-label-container”>
<br />
<div *ngFor=”let line of content.additionalInfo”>
<div class=”cx-card-label”>{{ line }}</div>
</div>
</div>
3.The final step is to populate the billing address. This has to be done in another component “projects/storefrontlib/src/cms-components/myaccount/payment-methods/payment-methods.component.ts”. If you observe the component’s HTML (payment-methods.component.html), one would notice that the component’s (payment-methods.component.ts) “getCardContent” method is called to display the contents of the card. So we have to plug our logic of displaying the billable address in “getCardContent“method. Before that let us create a new method “getAdditionalInfo“, that fetches and formats the billable address for a Card:
getAdditionalInfo(billingAddress: Address): string[] {
return [
//Title, First Name, Last Name
(billingAddress.title ? billingAddress.title : NIL) +
SPACE +
billingAddress.firstName +
SPACE +
billingAddress.lastName,
//Address – Line 1 & 2
billingAddress.line1 +
SPACE +
(billingAddress.line2 ? billingAddress.line2 : NIL),
//Town, Country
billingAddress.town +
SPACE +
(billingAddress.country.name ? billingAddress.country.name : NIL),
//Postal Code
billingAddress.postalCode,
];
}
Now call the method “getAdditionalInfo” in the method “getCardContent”, where the “Card” component is set:
additionalInfo: this.getAdditionalInfo(billingAddress)
With this, we will able to see the billable address in the “My Account -> Payment Details”.