Technical Changes in Spartacus 2.0
Note: Spartacus 2.x is no longer maintained. Please upgrade to the latest version.
Breaking Changes Introduced in 2.0
CMS page guard has less dependencies and all are public
Before 2.0, some dependencies of the CmsPageGuard
were not public, so the guard was not easily customizable. Now most of the logic (and dependencies) are moved to a new service called CmsPageGuardService
, and its dependencies are made public.
Config validation mechanism is now a separate module
Previously, config validator logic was part of ConfigModule
. If you are not using StorefrontFoundationModule
or any of its descendants, it’s required to import ConfigValidatorModule.forRoot()
in order to make config validators run.
Selectors removed from @spartacus/core
The ProductSelectors.getSelectedProductsFactory
was removed because it was outdated.
Factories removed from @spartacus/storefront public API
The pwaConfigurationFactory
, pwaFactory
, getStructuredDataFactory
and skipLinkFactory
were removed from the storefront library public API.
Bad Request Handler
The BadRequestHandler
handles 400 errors. Previously, it was handling not found
errors for OCC CMS pages because these were not returned as 404 errors. This was done in a generic way, by handling all other errors. Since the 1905 release of SAP Commerce Cloud, the OCC CMS returns a 404 error if a page is not found. Accordingly, we removed this special handling in the BadRequestHandler
. This might affect custom implementations that relied on this behavior, and in these cases, it is recommended to throw 404 errors from your back end, or to customize the BadRequestHandler
.
UrlMatcherFactoryService was renamed to UrlMatcherService and its methods were renamed
The service UrlMatcherFactoryService
was renamed to UrlMatcherService
and its methods were renamed as follows:
UrlMatcherFactoryService (removed) | UrlMatcherService (new counterpart) |
---|---|
getFalsyUrlMatcher | getFalsy |
getMultiplePathsUrlMatcher | getFromPaths |
getPathUrlMatcher | getFromPath |
getOppositeUrlMatcher | getOpposite |
getGlobUrlMatcher | getFromGlob |
New way to opt out from suffix routes for PDP and PLP
Before 2.0, the suffix routes **/p/:productCode
and **/c/:categoryCode
(added for backwards compatibility with Accelerators) were implemented in Spartacus using separate Angular Routes
objects. To opt out from them, you needed to dismantle the ProductDetailsPageModule
or the ProductListingPageModule
(or both), and reassemble them again without defining suffix routes.
Now that the separate objects for suffix routes were dropped, the suffix mechanism is now implemented in the original product
and category
routes, thanks to the support of the configurable Angular UrlMatcher
that arrived in Spartacus 2.0.
So the default config of Spartacus for the product
route now contains a matchers
property with an array containing PRODUCT_DETAILS_URL_MATCHER
, and the config for the category
route has PRODUCT_LISTING_URL_MATCHER
in the matchers
array by default. These matchers match both the paths
from the routing config as well as the suffix patterns **/p/:productCode
and **/c/:categoryCode
. To opt out from suffix patterns, set the config of the matchers
routes explicitly to null
, or to an array containing your custom matcher (or matchers).
Dropped functions in NavigationUIComponent
Since isTabbable
was never called, it no longer exists in the NavigationUIComponent
. Also, the getDepth
function was renamed to getTotalDepth
.
Anonymous consents feature toggle
The anonymous consents feature is now part of the core features, and the anonymousConsents
feature toggle has been removed.
Changes in PaymentMethodComponent
The PaymentMethodComponent
is now more similar to other checkout components, and the behavior is more aligned with the ShippingAddressComponent
. The changes to the public API are as follows:
setPaymentDetails
no longer has a third parameter. It should be used only for creating new payment details.createCard
method now has a third parameter for selected payment details. Parameters are also now typed.selectPaymentMethod
has different behavior now. It dispatches theCheckoutPaymentService
method for selecting the payment. Previously, it only modified the local component state.getCardContent
was removed and replaced with thecards$
observable, which emits all payment details cards, along with the payment details for each one.selectedPayment
variable was replaced with theselectedMethod$
observable.allowRouting
variable renamed toshouldRedirect
.deliveryAddress
,checkoutStepUrlNext
, andcheckoutStepUrlPrevious
are now protected variables. Previously, the were private.next
method has been removed. UsegoNext
instead.back
method has been removed. UsegoPrevious
instead.paymentMethodSelected
method has been removed. UseselectPaymentMethod
instead.
Changes in DeliveryModeComponent
The public API of this component has not been changed, but the behavior is now more aligned with other checkout components. Each change immediately triggers an update in the API. The default value is also set on the API during component initialization. As a result, the order summary is updated after every delivery mode change. On clicking the “next” button, the delivery mode is set one more time with the last selected value, and you get redirected to the next step only after an update has occurred on the API . When the delivery mode is set in the order summary component, you will see “shipping” instead of “estimated shipping”.
Removal of cmsPageLoadOnce feature flag
The cmsPageLoadOnce
feature flag has been removed. The same behavior is now achievable by configuring routing.loadStrategy
as RouteLoadStrategy.ONCE
.
Products endpoint configuration
The backend.occ.endpoints.product_scopes
configuration key was merged into the backend.occ.endpoints.product
key.
Launched in Smart Edit detection
The isLaunchInSmartEdit
method was removed from CmsService
. Instead, use the new isLaunchedInSmartEdit
method from SmartEditService
.
DynamicAttributeService
The addDynamicAttributes
method now has a different parameter order. The cmsRenderingContext
parameter is now the last parameter and it has a type.
CmsActions and CmsSelectors
The CmsActions
now have only parameter: payload
. Other parameters are now part of payload
.
The getComponentState
, getComponentEntities
, componentStateSelectorFactory
and componentSelectorFactory
were removed from CmsSelectors
. Use CMS selector factories instead.
Default OCC prefix
The default value for the backend.occ.prefix
configuration key is now /occ/v2/
. This is the default value for the 2005 release of SAP Commerce Cloud.
Cart components changes
The removeEntry
and updateEntry
methods were removed from the AddedToCartDialogComponent
component. Its logic is now contained in the getQuantityControl
method.
The updateItem
and isSaveForLaterEnabled
methods were removed from the CartItemComponent
component. The remove
and update
outputs were also removed. The isReadOnly
input is renamed to readonly
. The cartIsLoading
, parent
and potentialProductPromotions
inputs were removed. The new quantityControl
input was added to this component.
The ngOnInit
, isSaveForLaterEnabled
, updateEntry
and getPotentialProductPromotionsForItem
methods were removed from the CartItemListComponent
component. The potentialProductPromotions
input was removed.
Skip link changes
The SkipLinkComponent
methods blur
, tabNext
and tabPrev
were removed.
The skip link default configuration was simplified. Previously, by default, there were skip links for the top header, bottom header, facets, product list, and footer. Now there are default skip links only for the header, main content, and footer.
Product list component service
The clearSearchResults
method was removed from the ProductListComponentService
. The method was not needed in the ProductListComponent
anymore since the data will refresh on currency change. Instead, you can use clearResults
in ProductSearchService
.
Context change action not dispatched on the initial setting of the value
Before 2.0, the LanguageChange
NgRx action was dispatched on setting the initial value (as was also the case for CurrencyChange
). Moreover, the language (and currency) sometimes was initialized multiple times by the competing sources of truth (for example, routing, session storage, default config), which caused fake multiple language change actions in some circumstances (combinations of configuration and user journey).
Now the language change action is not dispatched on application start (and the same is true for currency). The language is initialized only once, using one source of truth. The first matched condition wins, according to the following order of priority:
- If the SSR transferred state is present, take the value from there. If not, proceed to the next condition.
- If the param was configured to be persisted from the URL, take the value from there. If not, proceed to the next condition. (When the value is not present in the current URL, the URL is updated using the default configured value and then we use this value.)
- If the value can be retrieved from session storage, take the value from there. If not, proceed to the next condition.
- Take the static default value from the config.
The same order of priority holds for currency. For base sites, however, only the first, second and fourth conditions apply, because there is no session storage as source.
WebComponentHandler is not provided by default
To enable Web Components support for CMS components, you have to provide the support in your app. The following is an example:
{
provide: ComponentHandler,
useExisting: WebComponentHandler,
multi: true,
},
Automated Migrations for Version 2
CheckoutService
no longer usesCartDataService
. This service usage was replaced with corresponding methods fromActiveCartService
(andAuthService
). These services needs to be provided toCheckoutService
.CheckoutPaymentService
no longer usesCartDataService
. This service usage was replaced with corresponding methods fromActiveCartService
(andAuthService
). These services needs to be provided forCheckoutPaymentService
.CheckoutDeliveryService
no longer usesCartDataService
. This service usage was replaced with corresponding methods fromActiveCartService
(andAuthService
). These services needs to be provided forCheckoutDeliveryService
.CheckoutGuard
no longer usesCheckoutConfig
. This config usage was replaced with corresponding methods fromCheckoutConfigService
,ExpressCheckoutService
,ActiveCartService
. These services needs to be provided forCheckoutGuard
.AddressBookComponentService
now usesCheckoutDeliveryService
. This service needs to be provided forAddressBookComponentService
.PromotionService
no longer usesCartService
. This service usage was replaced with corresponding methods fromActiveCartService
. This service needs to be provided forPromotionService
.CheckoutLoginComponent
no longer usesCartService
. This service usage was replaced with corresponding methods fromActiveCartService
. This service needs to be provided forCheckoutLoginComponent
.CheckoutDetailsService
no longer usesCartService
. This service usage was replaced with corresponding methods fromActiveCartService
. This service needs to be provided forCheckoutDetailsService
.NotCheckoutAuthGuard
no longer usesCartService
. This service usage was replaced with corresponding methods fromActiveCartService
. This service needs to be provided forNotCheckoutAuthGuard
.ShippingAddressComponent
no longer usesCartService
. This service usage was replaced with corresponding methods fromActiveCartService
. This service needs to be provided forShippingAddressComponent
.CheckoutPageMetaResolver
no longer usesCartService
. This service usage was replaced with corresponding methods fromActiveCartService
. This service needs to be provided forCheckoutPageMetaResolver
.AddToCartComponent
no longer usesCartService
. This service usage was replaced with corresponding methods fromActiveCartService
. This service needs to be provided forAddToCartComponent
.CartNotEmptyGuard
no longer usesCartService
. This service usage was replaced with corresponding methods fromActiveCartService
. This service needs to be provided forCartNotEmptyGuard
.CartTotalsComponent
no longer usesCartService
. This service usage was replaced with corresponding methods fromActiveCartService
. This service needs to be provided forCartTotalsComponent
.MiniCartComponent
no longer usesCartService
. This service usage was replaced with corresponding methods fromActiveCartService
. This service needs to be provided forMiniCartComponent
.CheckoutOrderSummaryComponent
no longer usesCartService
. This service usage was replaced with corresponding methods fromActiveCartService
. This service needs to be provided forCheckoutOrderSummaryComponent
.CheckoutProgressMobileTopComponent
no longer usesCartService
. This service usage was replaced with corresponding methods fromActiveCartService
. This service needs to be provided forCheckoutProgressMobileTopComponent
.PaymentMethodComponent
no longer usesCartService
. This service usage was replaced with corresponding methods fromActiveCartService
. This service needs to be provided forPaymentMethodComponent
.CheckoutAuthGuard
no longer usesCartService
. This service usage was replaced with corresponding methods fromActiveCartService
. This service needs to be provided forCheckoutAuthGuard
.CartPageLayoutHandler
no longer usesCartService
. This service usage was replaced with corresponding methods fromActiveCartService
.ActiveCartService
andSelectiveCartService
need to be provided inCartPageLayoutHandler
.SpartacusEventService
no longer usesCartService
. This service usage was replaced with corresponding methods fromActiveCartService.
This service needs to be provided forSpartacusEventService
.ClientAuthenticationTokenService
now usesOccEndpointsService
. This service needs to be provided forClientAuthenticationTokenService
.UserAuthenticationTokenService
now usesOccEndpointsService
. This service needs to be provided forUserAuthenticationTokenService
.OccCartEntryAdapter
no longer usesFeatureConfigService
. This service usage no longer uses the legacy methods:legacyAdd
,legacyRemove
, andlegacyUpdate
, and needs to be provided forOccCartEntryAdapter
.OccCartAdapter
no longer usesFeatureConfigService
. This service usage no longer uses the legacy methods:legacyLoadAll
,legacyLoad
, andlegacyCreate
, and needs to be provided forOccCartAdapter
.OccUserOrderAdapter
no longer usesFeatureConfigService
. This service usage no longer uses the legacy methods:legacyLoad
andlegacyLoadHistory
, and needs to be provided forOccUserOrderAdapter
.UserConsentService
now usesAuthService
. This service needs to be provided forUserConsentService
.UserOrderService
now usesAuthService
. This service needs to be provided forUserOrderService
.UserPaymentService
now usesAuthService
. This service needs to be provided forUserPaymentService
.UserService
now usesAuthService
. This service needs to be provided forUserService
.AddedToCartDialogComponent
no longer usesCartService
. This service usage was replaced with corresponding methods fromActiveCartService
. AlsoPromotionService
is now a required parameter. These services need to be provided forAddedToCartDialogComponent
.FormBuilder
no longer needs to be provided for this component.CartDetailsComponent
no longer usesCartService
andFeatureConfigService
. This service usage was replaced with corresponding methods fromActiveCartService
.PromotionService
,SelectiveCartService
,AuthService
andRoutingService
are now required parameters. These services need to be provided forCartDetailsComponent
. The deprecated methodisSaveForLaterEnabled()
was removed.ReviewSubmitComponent
no longer usesCartService
. This service usage was replaced with corresponding methods fromActiveCartService
.CheckoutConfigService
andPromotionService
are now required parameters. These services need to be provided forReviewSubmitComponent
.OrderDetailItemsComponent
now requiresPromotionService
. This service needs to be provided forOrderDetailItemsComponent
.OrderConfirmationItemsComponent
now requiresPromotionService
. This service needs to be provided forOrderConfirmationItemsComponent
.CartVoucherService
now requires the newActiveCartService
parameter. This service needs to be provided forCartVoucherService
.CartCouponComponent
no longer usesAuthService
,FeatureConfigService
andCartService
.CartService
service usage was replaced with corresponding methods fromActiveCartService
. Also,CustomerCouponService
is now a required parameter. These services need to be provided forCartCouponComponent
.LogoutGuard
no longer usesFeatureConfigService
, which was used previously to determine the feature flag.LoginFormComponent
now requires the following new parameters:WindowRef
,ActivatedRoute
andCheckoutConfigService
.RegisterComponent
no longer usesFeatureConfigService
,AuthService
andAuthRedirectService
. AlsoRoutingService
,AnonymousConsentsService
andAnonymousConsentsConfig
are now required parameters.StarRatingComponent
now requires the newRenderer2
parameter. This service needs to be provided forStarRatingComponent
.ProductService
now requiresProductLoadingService
.ProductCarouselComponent
no longer requiresFeatureConfigService
.CurrentProductService
no longer requiresFeatureConfigService
.ProductPageMetaResolver
no longer requiresFeatureConfigService
.ProductListComponent
now requires the newViewConfig
parameter. This config needs to be provided forProductListComponent
. TheviewPage
method was removed.isSamePage
is removed from theProductScrollComponent
because it is a deprecated method.ConfigurableRoutesService
no longer usesUrlMatcherFactoryService
, but instead uses its counterpart,UrlMatcherService
.ExternalRoutesService
no longer usesUrlMatcherFactoryService
, but instead uses its counterpart,UrlMatcherService
.OutletDirective
now requires newDeferLoaderService
andOutletRendererService
parameters. These services needs to be provided forOutletDirective
.ConsentManagementComponent
now requires theAnonymousConsentsConfig
,AnonymousConsentsService
andAuthService
parameters.ConsentManagementComponent
no longer uses theisLevel13
andisAnonymousConsentsEnabled
properties.ConsentManagementFormComponent
no longer uses theisLevel13
andisAnonymousConsentsEnabled
properties.AnonymousConsentDialogComponent
no longer uses theisLevel13
property.PlaceOrderComponent
now requires the newFormBuilder
parameter.CustomerCouponService
now requires the newAuthService
parameter. This service needs to be provided forCustomerCouponService
.UserInterestsService
now requires the newAuthService
parameter. This service needs to be provided forUserInterestsService
.UserNotificationPreferenceService
now requires the newAuthService
parameter. This service needs to be provided forUserNotificationPreferenceService
.UserAddressService
now requires the newAuthService
parameter. This service needs to be provided forUserAddressService
.ProductReviewsComponent
now requires the newChangeDetectorRef
parameter. This service needs to be provided forProductReviewsComponent
.SearchBoxComponent
now requires the newWindowRef
parameter. This service needs to be provided forSearchBoxComponent
.AddressBookComponent
now requires newTranslationService
,UserAddressService
andCheckoutDeliveryService
parameters. These services need to be provided forAddressBookComponent
.CartItemListComponent
no longer requiresFormBuilder
,FeatureConfigService
andCartService
.CartService
was replaced with corresponding methods fromActiveCartService
. The deprecated methodisSaveForLaterEnabled()
was removed.CartItemComponent
no longer usesFeatureConfigService
. The deprecated methodisSaveForLaterEnabled()
was removed.PaymentFormComponent
now requires the newUserAddressService
parameter.ComponentWrapperDirective
no longer uses theCmsService
param.DynamicAttributeService
requires the newSmartEditService
parameter.NavigationUIComponent
no longer uses theallowAlignToRight
property.StoreFinderSearchResultComponent
now requires the newStoreFinderConfig
parameter. This service needs to be provided forStoreFinderSearchResultComponent
.PageSlotComponent
now requires the newCmsComponentsService
andChangeDetectorRef
parameters. TheCmsComponentsService
is used to read the configurable page fold from the layout configuration. TheChangeDetectorRef
is needed to update the slot pending state asynchronously.TabParagraphContainerComponent
now requires the newWindowRef
parameter. This service needs to be provided forTabParagraphContainerComponent
.SelectiveCartService
now requires the newCartConfigService
parameter.QualtricsLoaderService
now requires Angular’s coreRendererFactory2
and no longer uses theQualtricsConfig
. The service has been refactored for better extensibility and reuse.QualtricsComponent
now requires theQualtricsConfig
to load the global qualtrics deployments script. This was a dependency in theQualtricsLoaderService
in 1.x. Also, the component no longer uses thequaltricsEnabled$
property.AmendOrderActionsComponent
now requires the newRoutingService
parameter.FooterNavigationComponent
no longer requires theAnonymousConsentsConfig
parameter.ProductFacetNavigationComponent
no longer requiresModalService
,ActivatedRoute
andProductListComponentService
. It now requiresBreakpointService
.StoreFinderGridComponent
no longer requiresRoutingService
. TheviewStore
andprepareRouteUrl
methods were removed.SkipLinkService
requires the newKeyboardFocusService
parameter.StorefrontComponent
requires the newElementRef
andKeyboardFocusService
parameters.AutoFocusDirective
,AutoFocusDirectiveModule
,OnlyNumberDirective
,OnlyNumberDirectiveModule
andFormUtils
were removed.authentication.kyma_enabled
configuration option has been removed. Kyma is now enabled by importingKymaModule
.features.anonymousConsents
configuration option has been removed. This feature is now part of the core set of features, and it is enabled by default.
State utility changes
LoaderState
,ProcessesLoaderState
,EntityState
,EntityLoaderState
,EntityProcessesLoaderState
were moved under theStateUtils
namespace.StateLoaderActions
,StateProcessesLoaderActions
,StateEntityActions
,StateEntityLoaderActions
,StateEntityProcessesLoaderActions
were removed. All actions are now accessible fromStateUtils
.StateLoaderSelectors
,StateProcessesLoaderSelectors
,StateEntitySelectors
,StateEntityLoaderSelectors
,StateEntityProcessesLoaderSelectors
were removed. All selectors are now accessible fromStateUtils
.loaderReducer
,processesLoaderReducer
,entityReducer
,entityLoaderReducer
,entityProcessesLoaderReducer
,initialEntityState
,initialLoaderState
,initialProcessesState
,getStateSlice
were moved under theStateUtils
namespace.ofLoaderLoad
,ofLoaderFail
,ofLoaderSuccess
methods were removed and are no longer available.entityStateSelector
was renamed toentityLoaderStateSelector
.EntityResetAction
was renamed toEntityLoaderResetAction
.
Automated migrations of page meta resolvers
The implementation of page meta data resolvers has been changed with 2.0. Previously, each meta resolver implementation had been responsible for resolving all page data, by implementing the abstract resolve
method from the abstract PageMetaResolver
. To allow for more flexibility and to simplify customizations, the individual implementations no longer implement the resolve
method. Only a specific resolver is required, such as the PageTitleResolver
. The PageMetaService
will invoke the specific resolvers when available. This is done by the registered resolverMethods
. You can further extend the list of resolverMethods
without changing the implementation of PageMetaService.resolve
.
These changes were introduced under a feature flag in version 1.3, and are standardized in 2.0. The FeatureConfigService
was used for this feature flag, and has been dropped from all constructors with version 2.0. This change will be migrated automatically.
The individual changes per class for 2.0 are the following:
PageMetaService
TheresolverMethods
access modifier changed from public to protected. Theresolve
method will invoke individual resolvers by iterating over theresolverMethods
.ContentPageMetaResolver
The deprecated methodresolve
is removed in 2.0. This method is no longer supported because individual resolve methods (resolveTitle
andresolveBreadcrumbs
) are invoked by thePageMetaService
directly. The individual resolvers no longer receive arguments, but use the localcms$
observable to resolve the required data.ProductPageMetaResolver
The deprecated methodresolve
is removed in 2.0. This method is no longer supported because individual resolve methods (resolveHeading
,resolveTitle
,resolveDescription
,resolveBreadcrumbs
,resolveImage
andresolveRobots
) are invoked by thePageMetaService
directly. The individual resolvers no longer receive arguments, but use the localproduct$
observable to resolve the required data.CategoryPageMetaResolver
The deprecated methodresolve
is removed in 2.0. This method is no longer supported because individual resolve methods (resolveTitle
andresolveBreadcrumbs
) are invoked by thePageMetaService
directly. The individual resolvers (resolveTitle
,resolveBreadcrumbs
) no longer receive arguments, but use the localsearchPage$
observable to resolve the required data.SearchPageMetaResolver
The deprecated methodresolve
is removed in 2.0. This method is no longer supported because the individual resolve method (resolveTitle
) is invoked by thePageMetaService
directly. The individual resolver (resolveTitle
) no longer receives arguments, but uses the localquery$
observable to resolve the required data.CartPageMetaResolver
The deprecated methodresolve
is removed in 2.0. This method is no longer supported because individual resolve methods (resolveTitle
,resolveRobots
) are invoked by thePageMetaService
directly. The individual resolvers (resolveTitle
,resolveRobots
) no longer receive arguments, but use the localcms$
observable to resolve the required data.CheckoutPageMetaResolver
The deprecated methodresolve
is removed in 2.0. This method is no longer supported because individual resolve methods (resolveTitle
,resolveRobots
) are invoked by thePageMetaService
directly. The individual resolvers (resolveTitle
,resolveRobots
) no longer receive arguments, but use the localcart$
observable to resolve the required data.-
CouponSearchPageResolver
FindProductPageMetaResolver
Thewas introduced in version 1.5, and has been renamed toFindProductPageMetaResolver
CouponSearchPageResolver
in version 2.0.The deprecated
resolve
method is removed in 2.0. This method is no longer supported because individual resolve methods (resolveTitle
,resolveBreadcrumbs
) are invoked by thePageMetaService
directly. The individual resolvers (resolveTitle
,resolveBreadcrumbs
) no longer receive arguments, but use the localtotal$
observable to resolve the required data.The
score
method was refactored heavily to better cope with synchronize router state. This resulted in a change in the constructor which should be migrated automatically.
Larger Refactoring for 2.0
Pagination Component
The reusable PaginationComponent
has been completely refactored for 2.0. The pagination component had various flaws in version 1 and the implementation wasn’t great either. The new version is fully configurable and easily extensible as the build logic is solely delegated to the new PaginationBuilder
.
The default configuration is more concise and shows a maximum of three pages with a start and end link.
The HTML and accompanying CSS is refactored as well. A clean DOM consists of only anchor links, nothing more. The availability and order of pagination links is driven by the configuration. The component is fully accessible and prepared for directionality as well.
Using anchor links is the preferred action for pagination links, but action links (using click
events) are still supported and used in various areas in Spartacus. The product listing page, however, is using anchor links.
For more information, see Pagination Component.
If you have used the pagination component directly, you should refactor the implementation, as the inputs have changed.
Payment Form Component
The method isContinueButtonDisabled()
because been removed as the submission button is no longer disabled by default.
Address Card Component
The component AddressCardComponent
has been completely removed and is replaced by CardComponent
. Use CardComponent
instead.
Storage sync mechanism change in multi-cart
The storage synchronization mechanism previously used to persist the active cart id had some limitations that caused bugs on multi-site stores (issue: https://github.com/SAP/spartacus/issues/6215).
The default storage sync configuration was removed from MultiCartStoreModule
. Instead, a state persistence mechanism has been added for multi-cart to provide the same behavior and to support multi-site stores. It is build on top of StatePersistenceService
. This is a new and recommended way to synchronize state to browser storage. For more information, see State Persistence.
Cart state and selectors removed
We are replacing the old cart
store feature (CART_DATA
, StateWithCart
, CartsState
, CART_FEATURE
, CartState
), along with its selectors (CartSelectors
), with a new cart state that was available in previous versions under multi-cart
. We recommend working with ActiveCartService
and MultiCartService
, which use the new cart
store feature under the hood. This allows us to support more carts (for example, wishlist, saved carts, and so on).
Typed payloads in NgRx actions
To avoid one type of bug (missing parameters) when dispatching NgRx actions, we added types to their payload. We want to be sure that we always have all required parameters. Additionally, creating new actions is easier with types, as you get better editor support when specifying the payload.
The following is a list of actions with changed payload type: CartAddEntry
, CartAddEntrySuccess
, CartRemoveEntry
, CartRemoveEntrySuccess
, CartUpdateEntry
, CartUpdateEntrySuccess
, AddEmailToCartSuccess
, MergeCartSuccess
, CartAddEntryFail
, CartRemoveEntryFail
, CartUpdateEntryFail
, CartRemoveVoucherFail
, CartRemoveVoucherSuccess
, CartAddVoucherFail
, CartAddVoucherSuccess
, CreateCart
, CreateCartFail
, CreateCartSuccess
, LoadCart
, LoadCartFail
, LoadCartSuccess
, LoadWishList
, LoadWishListSuccess
, AddEmailToCart
, AddEmailToCartFail
, MergeCart
, DeleteCartFail
, ClearCheckoutDeliveryModeFail
.
The following are removed actions: CreateMultiCart
, CreateMultiCartFail
, CreateMultiCartSuccess
, LoadMultiCart
, LoadMultiCartFail
, LoadMultiCartSuccess
, AddEmailToMultiCart
, AddEmailToMultiCartSuccess
, AddEmailToMultiCartFail
, MergeMultiCart
, MergeMultiCartSuccess
, ResetMultiCartDetails
, ClearCart
, RemoveTempCart
, ClearExpiredCoupons
.
The following are renamed actions: ClearMultiCartState
-> ClearCartState
The following are new actions:
-
LoadWishListFail
A dedicatedLoadWishListFail
action was added to maintain consistency in the wishlist. It is dispatched in the wishlist effects instead of theLoadCartFail
action. -
DeleteCartSuccess
TheDeleteCartSuccess
action was added to maintain consistency in the delete cart effect. It will be dispatched after DeleteCart action will successfully delete cart in backend. -
SetActiveCartId
TheSetActiveCartId
action was added to set the active cart id from the state persistence service.
Services changes
MultiCartService.createCart
and MultiCartService.mergeToCurrentCart
now have more strict types for parameters.
New Deprecations
ADD_VOUCHER_PROCESS_ID
const,CartResetAddVoucher
action: we plan to migrate from the add voucher process to cart voucher eventsCartProcessesIncrement
andCartProcessesDecrement
: instead, extend EntityProcesses in actionsCartVoucherService
methods:getAddVoucherResultError
,getAddVoucherResultSuccess
,getAddVoucherResultLoading
andresetAddVoucherProcessingState
. These methods are replaced with event listeners.
Forms Changes
Naming convention
From 2.0, FormGroups
will be named according to the components they are used in. For example, FormGroup
in loginComponent
will be named loginForm
.
New FormGroup list
Component name | Old FormGroup | New FormGroup | Notes |
---|---|---|---|
PlaceOrderComponent |
- | checkoutSubmitForm |
new FormGroup added |
AddressFormComponent |
address |
addressForm |
|
PaymentFormComponent |
billingAddress |
billingAddressForm |
BillingAddressComponent was removed (read more below) |
PaymentFormComponent |
payment |
paymentForm |
|
RegisterComponent |
userRegistrationForm |
registerForm |
|
CSAgentLoginFormComponent |
form |
csAgentLoginForm |
|
CustomerSelectionComponent |
form |
customerSelectionForm |
|
CartCouponComponent |
form |
couponForm |
|
ForgotPasswordComponent |
form |
forgotPasswordForm |
|
ResetPasswordFormComponent |
form |
resetPasswordForm |
|
UpdateEmailFormComponent |
form |
updateEmailForm |
|
UpdatePasswordFormComponent |
form |
updatePasswordForm |
|
UpdateProfileFormComponent |
form |
updateProfileForm |
|
CheckoutLoginComponent |
form |
checkoutLoginForm |
|
LoginFormComponent |
form |
loginForm |
File removals
Due to changes in forms and form-related functionalities, the form-utils
file was removed completely, and its functionalities are now handled by FormErrorsComponent
. Also due to the aforementioned changes, BillingAddressFormComponent
was removed and its functionalities were moved to PaymentFormComponent
. The same is true for the module: instead of BillingAddressFormModule
, use PaymentFormModule
.
How to Use FormErrorsComponent
Preface
This component was created with easy usage in mind. The only thing you have to do is pass a form control to it as an attribute [control]
and the component will handle everything for you, such as icon rendering, message, showing/hiding validation error, and so on.
Useful information
- You can use the
FormErrors
component in any place you want, so you do not have to place it right after a related control element. For example, you can place it in a custom popup. - The
FormErrors
component uses translation keys from thecommon
chunk. - Each translation is mapped to specific validation error names, such as
cxPasswordsMustMatch
, for example. - The visuals of the controls (red border) are fully handled by CSS. They take advantage of the
ng-...
form CSS classes (valid, dirty, touched). FormErrors
visibility is also relying on similar CSS classes (.control-valid
,.control-dirty
,.control-touched
). As a result, you can use it in any place you want.
Example
<form [formGroup]="testForm">
<input formControlName="myInput" />
<cx-form-errors [control]="testForm.get('myInput')"> <!-- pass the control -->
</form>
<cx-form-errors [control]="testForm.get('myInput')"> <!-- this will also work -->
Changes to components’ variables, methods, etc
Component | Change type | Old value | New value |
---|---|---|---|
PlaceOrderComponent |
variable | tAndCToggler |
removed |
PlaceOrderComponent |
method | toggleTAndC |
removed |
PlaceOrderComponent |
method | placeOrder |
submitForm |
ForgotPasswordComponent |
variable | submitted |
removed |
ResetPasswordFormComponent |
variable | submitted |
removed |
UpdateEmailFormComponent |
variable | submitted |
removed |
UpdateEmailFormComponent |
method | isEmailConfirmNotValid |
removed |
UpdateEmailFormComponent |
method | isNotValid |
removed |
UpdatePasswordFormComponent |
output | submitted |
submitted |
UpdatePasswordFormComponent |
method | isNotValid |
removed |
UpdatePasswordFormComponent |
method | isPasswordConfirmNotValid |
removed |
UpdateProfileFormComponent |
output | submitted |
submitted |
UpdateProfileFormComponent |
method | isNotValid |
removed |
CSAgentLoginFormComponent |
method | isNotValid |
removed |
CheckoutLoginComponent |
method | isNotValid |
removed |
CheckoutLoginComponent |
method | isEmailConfirmInvalid |
removed |
LoginFormComponent |
method | login |
submitForm |
LoginFormComponent |
method | - | loginUser |
RegisterComponent |
method | submit |
submitForm |
RegisterComponent |
method | - | registerUser |
RegisterComponent |
variable | isNewRegisterFlowEnabled |
removed |
RegisterComponent |
variable | isAnonymousConsentEnabled |
removed |
CustomFormValidators |
validator | emailDomainValidator |
removed |
CustomFormValidators |
validator | matchPassword |
removed |
AmendOrderActionsComponent |
input | isValid |
amendOrderForm |
PaymentFormComponent |
method | showSameAsShippingAddressCheckbox |
replaced with observable showSameAsShippingAddressCheckbox$ |
Store Finder Changes
In StoreFinderConfig
, the radius
parameter of the googleMaps?
parameter is now configurable.
Save for Later Configuration
The saveForLater
feature flag was removed.
Instead, use cart configuration to enable/disable saveForLater feature. The following is an example:
cart: {
selectiveCart: {
enabled: true|false
}
}
Translations Updates
New translations have been added: small stylistic changes in the default values of loginForm.dontHaveAccount
, productList.appliedFilter
, and productFacetNavigation.appliedFilter
, and a new formErrors
translation group was added to the common
chunk.
CDS Library Breaking Changes
- Enum
ProfileTagEventNames.LOADED
value was removed. ProfileTagEventService.addTracker
now returnsObservable<string>
instead ofObservable<Event>
.
Peer Dependencies
We updated peer dependencies for every library to correctly list all dependencies if you don’t use the storefront library. Previously, we only maintained this list for @spartacus/storefront
.
Now, during any library installation, you will see which other packages you have to install in the project.
Deprecated Since 1.5
API | Replacement | Notes |
---|---|---|
WishlistEffects, CartEffects, CartVoucherEffects, CartEntryEffects, effects | Create your own effects in a separate class and take into account the default behavior from effects | We didn’t plan to export effects in the first place. Cart effects in the public API were a mistake. If you extended this class, you should move your effects to a separate class and keep in mind that default effects will be working. |
getReducers, reducerToken, reducerProvider, clearCartState, metaReducers, clearMultiCartState, multiCartMetaReducers, multiCartReducerToken, getMultiCartReducers, multiCartReducerProvider | Extend cart behavior in higher level (facade) or use custom actions for your specific use case | We didn’t plan to export reducers and utilities for reducers in the first place. Cart reducers in the public API were a mistake. Any changes to reducers should be handled in a different layer (facade) or separate store module. Keep in mind that default reducer behavior will be working under the hood. |
CartDetailsComponent.getAllPromotionsForCart method removed |
Use PromotionService |
PromotionService is now the main promotion data source. Whenever you need promotions information, you should use this service. |
OrderDetailItemsComponent.getConsignmentProducts method removed |
Use OrderConsignedEntriesComponent instead |
This functionality has been extracted into a separate component. |
CartItemComponent.potentialProductPromotions input removed |
Use PromotionService |
PromotionService is now the main promotion data source. Whenever you need promotions information, you should use this service. |
CartItemListComponent.potentialProductPromotions input removed |
Use PromotionService |
PromotionService is now the main promotion data source. Whenever you need promotions information, you should use this service. |
CartItemListComponent.getPotentialProductPromotionsForItem method removed |
Use PromotionService |
PromotionService is now the main promotion data source. Whenever you need promotions information, you should use this service. |
ProductImagesComponent.isThumbsEmpty property removed |
Use thumbs$ observable instead |
- |
KymaServices const removed |
Use OpenIdAuthenticationTokenService directly |
- |
Deprecated Since 1.4
API | Replacement | Notes |
---|---|---|
config i18n.backend.crossDomain |
- | It is not needed anymore since using Angular HttpClient for loading i18n assets |
CartService removed |
Use ActiveCartService instead |
ActiveCartService has exactly the same name, arguments and return type for most of the methods from CartService . One function was renamed: getLoaded is changed to isStable to better describe function behavior. Two methods are not present in ActiveCartService . The getCartMergeComplete method was removed on purpose. Cart merging is an implementation detail of OCC and we don’t consider that information useful. Instead, you can rely on the isStable method that will correctly present the state of the cart. During cart merge, it will emit false values. A rule of thumb is to only dispatch cart modifications (for example, addEntry , addEmail ) when isStable emits true . The addVoucher method is also not available in ActiveCartService . Instead, use the CartVoucherService.addVoucher method. |
CartDataService removed |
Use methods from ActiveCartService and AuthService |
Our libraries are generally moving towards reactive programming and observables. CartDataService used completely different patterns and it was hard to follow if existing data was already updated, or represented a previous cart state. The following are replacements for CartDataService properties: userId -> replace usage with AuthService.getOccUserId() ; cart -> replace usage with ActiveCartService.getActive() ; cartId -> replace usage with ActiveCartService.getActiveCartId() ; isGuestCart -> replace usage with ActiveCartService.isGuestCart() . The hasCart property doesn’t have a direct replacement. Instead, you can look into the ActiveCartService.getActive() method output to see if it emitted an empty object (which means that there is no cart). |
ProductService and CurrentProductService use product scopes |
- | In some cases, the current product won’t return the full product model. You should use scopes to optimize back end calls related to product data. |
withCredentialsInterceptorProvider |
It is provided by default in OccModule |
- |
Deprecated Since 1.3
API | Replacement | Notes |
---|---|---|
PageMetaResolver.resolve() | Use individual resolvers | The caller PageMetaService service is improved to expect all individual resolvers instead, so that the code is more easily extensible. |
initSiteContextRoutesHandler , siteContextParamsProviders |
- | The constants were not meant to be exported in the public API. |
inititializeContext , contextServiceProviders |
- | The constants were not meant to be exported in the public API. |
Deprecated Since 1.2
API | Replacement | Notes |
---|---|---|
CheckoutActions.ClearCheckoutDeliveryModeSuccess() | CheckoutActions.ClearCheckoutDeliveryModeSuccess(payload) | The ClearCheckoutDeliveryModeSuccess action requires a payload. CheckoutActions.ClearCheckoutDeliveryModeSuccess(payload: { userId: string; cartId: string }) |
ANONYMOUS_USERID |
OCC_USER_ID_ANONYMOUS |
OCC constants are now available under the OCC prefix to make it more clear that these variables are related to OCC . |
AddressBookComponentService.addUserAddress(userAddressService: UserAddressService) | AddressBookComponentService(userAddressService, checkoutDeliveryService) | The constructor now also uses the CheckoutDeliveryService . AddressBookComponentService(userAddressService: UserAddressService, checkoutDeliveryService: CheckoutDeliveryService) |
CheckoutGuard(router: Router, config: CheckoutConfig, routingConfigService: RoutingConfigService) | CheckoutGuard(router, routingConfigService, checkoutConfigService, expressCheckoutService, cartService) | The constructor now uses new dependencies. CheckoutGuard(router: Router, routingConfigService: RoutingConfigService, checkoutConfigService: CheckoutConfigService, expressCheckoutService: ExpressCheckoutService, cartService: ActiveCartService) |
Deprecated Since 1.1
API | Replacement | Notes |
---|---|---|
cxApi.CmsComponentData |
cxApi.cmsComponentData | - |
OccCartEntryAdapter.getCartEndpoint |
Use configurable endpoints | - |
OccCartAdapter.getCartEndpoint |
Use configurable endpoints | - |
OccUserOrderAdapter.getOrderEndpoint |
Use configurable endpoints | - |
Shipping Address component variables and methods removed
Support for declared variables dropped:
cards
This variable will no longer be in use. Use thecards$
observable instead.goTo
This variable will no longer be in use. Avoid using it.setAddress
This variable will no longer be in use. UseselectAddress(address: Address)
instead.setAddressSub
This variable will no longer be in use. Avoid using it.selectedAddressSub
This variable will no longer be in use. Use theselectedAddress$
observable instead.checkoutStepUrlNext
This variable will no longer be in use. UseCheckoutConfigService.getNextCheckoutStepUrl(this.activatedRoute)
instead.checkoutStepUrlPrevious
This variable will no longer be in use. UseCheckoutConfigService.getPreviousCheckoutStepUrl(this.activatedRoute)
instead.selectedAddress
This variable will no longer be in use. UseselectedAddress$
observable instead.
Support for functions dropped:
addressSelected
This method will no longer be in use. UseselectAddress(address: Address)
instead.back
This method will no longer be in use. UsegoPrevious()
instead.next
This method will no longer be in use. UsegoNext()
instead.addNewAddress
This method will no longer be in use. UseaddAddress(address: Address)
instead.ngOnDestroy
This method will no longer be in use. Remove.