Address normalizers
Address management in the Storefront requires bidirectional normalization.
Retrieving Addresses
To map SAP Address
into Unified Model, following normalizers are used:
normalizeAddress
: This function is used to retrieve an address that has been saved in the checkout process.normalizeCustomerAddress
: When a customer retrieves one of the addresses they've saved, this function comes into play.
Saving Address
When a customer sets a shipping address during the checkout process, the SetCartAddress
method is utilized. Here, a critical aspect arises in scenarios involving SAP Commerce Cloud. To ensure the correct handling of new addresses in SAP, a special unnormalization process is required.
unnormalizeAddress
To accurately save a new address in SAP, we need to unnormalize the address data. This means mapping the unifiedSfCreateAddressBody
format used within the Storefront into the specific structure required by SAP, known asCreateAddressProps
. This unnormalization step ensures that the address is correctly processed and stored in SAP, maintaining data integrity between the Storefront and SAP.
Parameters
normalizeAddress
Name | Type | Default value | Description |
---|---|---|---|
context | NormalizerContext | context needed for the normalizer. transformImageUrl is added to transform line items image urls | |
address | Address | SAP Address |
normalizeCustomerAddress
Name | Type | Default value | Description |
---|---|---|---|
context | NormalizerContext | context needed for the normalizer. | |
address | Address | SAP Address. If address does not contain the id , an error is thrown |
unnormalizeAddress
Name | Type | Default value | Description |
---|---|---|---|
context | NormalizerContext | context needed for the normalizer. | |
address | SfCreateAddressBody | Unified address body sent in the request from the Storefront |
Extending
The SfCustomerAddress
model represents a reusable address, which customer decided to store. It is used within customer address methods, as for example GetCustomerAddresses
. If any of this models don't contain the information you need for your Storefront, you can extend its logic using the addCustomFields
API. In the following example we extend the normalizeCustomerAddress
with visibleInAddressBook
field which is available on SAP Address.
export const unifiedApiExtension = createUnifiedExtension({
normalizers: {
addCustomFields: [
{
normalizeCustomerAddress: (context, address) => ({
visibleInAddressBook: address?.visibleInAddressBook ?? false,
}),
},
],
},
config: {
...
},
});
Similarly if you want to change the mapping of unnormalizeAddress
function you can customize it within addCustomFields
.
Source
/* eslint-disable complexity */
import { maybe } from "@shared/utils";
import { defineNormalizer } from "../defineNormalizer";
export const normalizeAddress = defineNormalizer.normalizeAddress((_context, address) => {
return {
titleCode: maybe(address?.titleCode),
address1: maybe(address?.line1),
address2: maybe(address?.line2),
city: maybe(address?.town),
country: maybe(address?.country?.isocode),
firstName: maybe(address?.firstName),
lastName: maybe(address?.lastName),
phoneNumber: maybe(address?.phone),
postalCode: maybe(address?.postalCode),
state: maybe(address?.district),
};
});
export const normalizeCustomerAddress = defineNormalizer.normalizeCustomerAddress(
(context, address) => {
if (!address.id) {
throw new Error("Address is not a valid customer address. `id` field is missing");
}
return {
id: address.id,
...normalizeAddress(context, address),
};
},
);
export const unnormalizeAddress = defineNormalizer.unnormalizeAddress((_context, address) => {
const {
titleCode,
firstName,
lastName,
postalCode,
country,
city,
address1,
address2,
phoneNumber,
state,
} = address;
if (
!titleCode ||
!firstName ||
!lastName ||
!postalCode ||
!country ||
!city ||
!address1 ||
!phoneNumber
) {
throw new Error("Address is not a valid customer address. Some required fields are missing");
}
return {
titleCode,
firstName,
lastName,
postalCode,
country: { isocode: country },
town: city,
line1: address1,
line2: address2 || undefined,
phone: phoneNumber,
district: state || undefined,
};
});