Technical Changes in Spartacus 2.0
Note: Spartacus 3.x is no longer maintained. Please upgrade to the latest version.
Note: Spartacus 3.x was tested with SAP Commerce Cloud versions 1905 to 2105. Spartacus 3.x has not been verified to work with (and is not guaranteed to work with) SAP Commerce Cloud 2211 or later releases.
Table of Contents
- Breaking Changes Introduced in 2.0
- CMS page guard has less dependencies and all are public
- Config validation mechanism is now a separate module
- Selectors removed from @spartacus/core
- Factories removed from @spartacus/storefront public API
- Bad Request Handler
- UrlMatcherFactoryService was renamed to UrlMatcherService and its methods were renamed
- New way to opt out from suffix routes for PDP and PLP
- Dropped functions in NavigationUIComponent
- Anonymous consents feature toggle
- Changes in PaymentMethodComponent
- Changes in DeliveryModeComponent
- Removal of cmsPageLoadOnce feature flag
- Products endpoint configuration
- Launched in Smart Edit detection
- DynamicAttributeService
- CmsActions and CmsSelectors
- Default OCC prefix
- Cart components changes
- Skip link changes
- Product list component service
- Context change action not dispatched on the initial setting of the value
- WebComponentHandler is not provided by default
- Automated Migrations for Version 2
- Larger Refactoring for 2.0
- New Deprecations
- Forms Changes
- How to Use FormErrorsComponent
- Store Finder Changes
- Save for Later Configuration
- Translations Updates
- CDS Library Breaking Changes
- Peer Dependencies
- Deprecated Since 1.5
- Deprecated Since 1.4
- Deprecated Since 1.3
- Deprecated Since 1.2
- Deprecated Since 1.1
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:
setPaymentDetailsno longer has a third parameter. It should be used only for creating new payment details.createCardmethod now has a third parameter for selected payment details. Parameters are also now typed.selectPaymentMethodhas different behavior now. It dispatches theCheckoutPaymentServicemethod for selecting the payment. Previously, it only modified the local component state.getCardContentwas removed and replaced with thecards$observable, which emits all payment details cards, along with the payment details for each one.selectedPaymentvariable was replaced with theselectedMethod$observable.allowRoutingvariable renamed toshouldRedirect.deliveryAddress,checkoutStepUrlNext, andcheckoutStepUrlPreviousare now protected variables. Previously, the were private.nextmethod has been removed. UsegoNextinstead.backmethod has been removed. UsegoPreviousinstead.paymentMethodSelectedmethod has been removed. UseselectPaymentMethodinstead.
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
CheckoutServiceno longer usesCartDataService. This service usage was replaced with corresponding methods fromActiveCartService(andAuthService). These services needs to be provided toCheckoutService.CheckoutPaymentServiceno longer usesCartDataService. This service usage was replaced with corresponding methods fromActiveCartService(andAuthService). These services needs to be provided forCheckoutPaymentService.CheckoutDeliveryServiceno longer usesCartDataService. This service usage was replaced with corresponding methods fromActiveCartService(andAuthService). These services needs to be provided forCheckoutDeliveryService.CheckoutGuardno longer usesCheckoutConfig. This config usage was replaced with corresponding methods fromCheckoutConfigService,ExpressCheckoutService,ActiveCartService. These services needs to be provided forCheckoutGuard.AddressBookComponentServicenow usesCheckoutDeliveryService. This service needs to be provided forAddressBookComponentService.PromotionServiceno longer usesCartService. This service usage was replaced with corresponding methods fromActiveCartService. This service needs to be provided forPromotionService.CheckoutLoginComponentno longer usesCartService. This service usage was replaced with corresponding methods fromActiveCartService. This service needs to be provided forCheckoutLoginComponent.CheckoutDetailsServiceno longer usesCartService. This service usage was replaced with corresponding methods fromActiveCartService. This service needs to be provided forCheckoutDetailsService.NotCheckoutAuthGuardno longer usesCartService. This service usage was replaced with corresponding methods fromActiveCartService. This service needs to be provided forNotCheckoutAuthGuard.ShippingAddressComponentno longer usesCartService. This service usage was replaced with corresponding methods fromActiveCartService. This service needs to be provided forShippingAddressComponent.CheckoutPageMetaResolverno longer usesCartService. This service usage was replaced with corresponding methods fromActiveCartService. This service needs to be provided forCheckoutPageMetaResolver.AddToCartComponentno longer usesCartService. This service usage was replaced with corresponding methods fromActiveCartService. This service needs to be provided forAddToCartComponent.CartNotEmptyGuardno longer usesCartService. This service usage was replaced with corresponding methods fromActiveCartService. This service needs to be provided forCartNotEmptyGuard.CartTotalsComponentno longer usesCartService. This service usage was replaced with corresponding methods fromActiveCartService. This service needs to be provided forCartTotalsComponent.MiniCartComponentno longer usesCartService. This service usage was replaced with corresponding methods fromActiveCartService. This service needs to be provided forMiniCartComponent.CheckoutOrderSummaryComponentno longer usesCartService. This service usage was replaced with corresponding methods fromActiveCartService. This service needs to be provided forCheckoutOrderSummaryComponent.CheckoutProgressMobileTopComponentno longer usesCartService. This service usage was replaced with corresponding methods fromActiveCartService. This service needs to be provided forCheckoutProgressMobileTopComponent.PaymentMethodComponentno longer usesCartService. This service usage was replaced with corresponding methods fromActiveCartService. This service needs to be provided forPaymentMethodComponent.CheckoutAuthGuardno longer usesCartService. This service usage was replaced with corresponding methods fromActiveCartService. This service needs to be provided forCheckoutAuthGuard.CartPageLayoutHandlerno longer usesCartService. This service usage was replaced with corresponding methods fromActiveCartService.ActiveCartServiceandSelectiveCartServiceneed to be provided inCartPageLayoutHandler.SpartacusEventServiceno longer usesCartService. This service usage was replaced with corresponding methods fromActiveCartService.This service needs to be provided forSpartacusEventService.ClientAuthenticationTokenServicenow usesOccEndpointsService. This service needs to be provided forClientAuthenticationTokenService.UserAuthenticationTokenServicenow usesOccEndpointsService. This service needs to be provided forUserAuthenticationTokenService.OccCartEntryAdapterno longer usesFeatureConfigService. This service usage no longer uses the legacy methods:legacyAdd,legacyRemove, andlegacyUpdate, and needs to be provided forOccCartEntryAdapter.OccCartAdapterno longer usesFeatureConfigService. This service usage no longer uses the legacy methods:legacyLoadAll,legacyLoad, andlegacyCreate, and needs to be provided forOccCartAdapter.OccUserOrderAdapterno longer usesFeatureConfigService. This service usage no longer uses the legacy methods:legacyLoadandlegacyLoadHistory, and needs to be provided forOccUserOrderAdapter.UserConsentServicenow usesAuthService. This service needs to be provided forUserConsentService.UserOrderServicenow usesAuthService. This service needs to be provided forUserOrderService.UserPaymentServicenow usesAuthService. This service needs to be provided forUserPaymentService.UserServicenow usesAuthService. This service needs to be provided forUserService.AddedToCartDialogComponentno longer usesCartService. This service usage was replaced with corresponding methods fromActiveCartService. AlsoPromotionServiceis now a required parameter. These services need to be provided forAddedToCartDialogComponent.FormBuilderno longer needs to be provided for this component.CartDetailsComponentno longer usesCartServiceandFeatureConfigService. This service usage was replaced with corresponding methods fromActiveCartService.PromotionService,SelectiveCartService,AuthServiceandRoutingServiceare now required parameters. These services need to be provided forCartDetailsComponent. The deprecated methodisSaveForLaterEnabled()was removed.ReviewSubmitComponentno longer usesCartService. This service usage was replaced with corresponding methods fromActiveCartService.CheckoutConfigServiceandPromotionServiceare now required parameters. These services need to be provided forReviewSubmitComponent.OrderDetailItemsComponentnow requiresPromotionService. This service needs to be provided forOrderDetailItemsComponent.OrderConfirmationItemsComponentnow requiresPromotionService. This service needs to be provided forOrderConfirmationItemsComponent.CartVoucherServicenow requires the newActiveCartServiceparameter. This service needs to be provided forCartVoucherService.CartCouponComponentno longer usesAuthService,FeatureConfigServiceandCartService.CartServiceservice usage was replaced with corresponding methods fromActiveCartService. Also,CustomerCouponServiceis now a required parameter. These services need to be provided forCartCouponComponent.LogoutGuardno longer usesFeatureConfigService, which was used previously to determine the feature flag.LoginFormComponentnow requires the following new parameters:WindowRef,ActivatedRouteandCheckoutConfigService.RegisterComponentno longer usesFeatureConfigService,AuthServiceandAuthRedirectService. AlsoRoutingService,AnonymousConsentsServiceandAnonymousConsentsConfigare now required parameters.StarRatingComponentnow requires the newRenderer2parameter. This service needs to be provided forStarRatingComponent.ProductServicenow requiresProductLoadingService.ProductCarouselComponentno longer requiresFeatureConfigService.CurrentProductServiceno longer requiresFeatureConfigService.ProductPageMetaResolverno longer requiresFeatureConfigService.ProductListComponentnow requires the newViewConfigparameter. This config needs to be provided forProductListComponent. TheviewPagemethod was removed.isSamePageis removed from theProductScrollComponentbecause it is a deprecated method.ConfigurableRoutesServiceno longer usesUrlMatcherFactoryService, but instead uses its counterpart,UrlMatcherService.ExternalRoutesServiceno longer usesUrlMatcherFactoryService, but instead uses its counterpart,UrlMatcherService.OutletDirectivenow requires newDeferLoaderServiceandOutletRendererServiceparameters. These services needs to be provided forOutletDirective.ConsentManagementComponentnow requires theAnonymousConsentsConfig,AnonymousConsentsServiceandAuthServiceparameters.ConsentManagementComponentno longer uses theisLevel13andisAnonymousConsentsEnabledproperties.ConsentManagementFormComponentno longer uses theisLevel13andisAnonymousConsentsEnabledproperties.AnonymousConsentDialogComponentno longer uses theisLevel13property.PlaceOrderComponentnow requires the newFormBuilderparameter.CustomerCouponServicenow requires the newAuthServiceparameter. This service needs to be provided forCustomerCouponService.UserInterestsServicenow requires the newAuthServiceparameter. This service needs to be provided forUserInterestsService.UserNotificationPreferenceServicenow requires the newAuthServiceparameter. This service needs to be provided forUserNotificationPreferenceService.UserAddressServicenow requires the newAuthServiceparameter. This service needs to be provided forUserAddressService.ProductReviewsComponentnow requires the newChangeDetectorRefparameter. This service needs to be provided forProductReviewsComponent.SearchBoxComponentnow requires the newWindowRefparameter. This service needs to be provided forSearchBoxComponent.AddressBookComponentnow requires newTranslationService,UserAddressServiceandCheckoutDeliveryServiceparameters. These services need to be provided forAddressBookComponent.CartItemListComponentno longer requiresFormBuilder,FeatureConfigServiceandCartService.CartServicewas replaced with corresponding methods fromActiveCartService. The deprecated methodisSaveForLaterEnabled()was removed.CartItemComponentno longer usesFeatureConfigService. The deprecated methodisSaveForLaterEnabled()was removed.PaymentFormComponentnow requires the newUserAddressServiceparameter.ComponentWrapperDirectiveno longer uses theCmsServiceparam.DynamicAttributeServicerequires the newSmartEditServiceparameter.NavigationUIComponentno longer uses theallowAlignToRightproperty.StoreFinderSearchResultComponentnow requires the newStoreFinderConfigparameter. This service needs to be provided forStoreFinderSearchResultComponent.PageSlotComponentnow requires the newCmsComponentsServiceandChangeDetectorRefparameters. TheCmsComponentsServiceis used to read the configurable page fold from the layout configuration. TheChangeDetectorRefis needed to update the slot pending state asynchronously.TabParagraphContainerComponentnow requires the newWindowRefparameter. This service needs to be provided forTabParagraphContainerComponent.SelectiveCartServicenow requires the newCartConfigServiceparameter.QualtricsLoaderServicenow requires Angular’s coreRendererFactory2and no longer uses theQualtricsConfig. The service has been refactored for better extensibility and reuse.QualtricsComponentnow requires theQualtricsConfigto load the global qualtrics deployments script. This was a dependency in theQualtricsLoaderServicein 1.x. Also, the component no longer uses thequaltricsEnabled$property.AmendOrderActionsComponentnow requires the newRoutingServiceparameter.FooterNavigationComponentno longer requires theAnonymousConsentsConfigparameter.ProductFacetNavigationComponentno longer requiresModalService,ActivatedRouteandProductListComponentService. It now requiresBreakpointService.StoreFinderGridComponentno longer requiresRoutingService. TheviewStoreandprepareRouteUrlmethods were removed.SkipLinkServicerequires the newKeyboardFocusServiceparameter.StorefrontComponentrequires the newElementRefandKeyboardFocusServiceparameters.AutoFocusDirective,AutoFocusDirectiveModule,OnlyNumberDirective,OnlyNumberDirectiveModuleandFormUtilswere removed.authentication.kyma_enabledconfiguration option has been removed. Kyma is now enabled by importingKymaModule.features.anonymousConsentsconfiguration 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,EntityProcessesLoaderStatewere moved under theStateUtilsnamespace.StateLoaderActions,StateProcessesLoaderActions,StateEntityActions,StateEntityLoaderActions,StateEntityProcessesLoaderActionswere removed. All actions are now accessible fromStateUtils.StateLoaderSelectors,StateProcessesLoaderSelectors,StateEntitySelectors,StateEntityLoaderSelectors,StateEntityProcessesLoaderSelectorswere removed. All selectors are now accessible fromStateUtils.loaderReducer,processesLoaderReducer,entityReducer,entityLoaderReducer,entityProcessesLoaderReducer,initialEntityState,initialLoaderState,initialProcessesState,getStateSlicewere moved under theStateUtilsnamespace.ofLoaderLoad,ofLoaderFail,ofLoaderSuccessmethods were removed and are no longer available.entityStateSelectorwas renamed toentityLoaderStateSelector.EntityResetActionwas 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
TheresolverMethodsaccess modifier changed from public to protected. Theresolvemethod will invoke individual resolvers by iterating over theresolverMethods.ContentPageMetaResolver
The deprecated methodresolveis removed in 2.0. This method is no longer supported because individual resolve methods (resolveTitleandresolveBreadcrumbs) are invoked by thePageMetaServicedirectly. The individual resolvers no longer receive arguments, but use the localcms$observable to resolve the required data.ProductPageMetaResolver
The deprecated methodresolveis removed in 2.0. This method is no longer supported because individual resolve methods (resolveHeading,resolveTitle,resolveDescription,resolveBreadcrumbs,resolveImageandresolveRobots) are invoked by thePageMetaServicedirectly. The individual resolvers no longer receive arguments, but use the localproduct$observable to resolve the required data.CategoryPageMetaResolverThe deprecated methodresolveis removed in 2.0. This method is no longer supported because individual resolve methods (resolveTitleandresolveBreadcrumbs) are invoked by thePageMetaServicedirectly. The individual resolvers (resolveTitle,resolveBreadcrumbs) no longer receive arguments, but use the localsearchPage$observable to resolve the required data.SearchPageMetaResolverThe deprecated methodresolveis removed in 2.0. This method is no longer supported because the individual resolve method (resolveTitle) is invoked by thePageMetaServicedirectly. The individual resolver (resolveTitle) no longer receives arguments, but uses the localquery$observable to resolve the required data.CartPageMetaResolver
The deprecated methodresolveis removed in 2.0. This method is no longer supported because individual resolve methods (resolveTitle,resolveRobots) are invoked by thePageMetaServicedirectly. The individual resolvers (resolveTitle,resolveRobots) no longer receive arguments, but use the localcms$observable to resolve the required data.CheckoutPageMetaResolver
The deprecated methodresolveis removed in 2.0. This method is no longer supported because individual resolve methods (resolveTitle,resolveRobots) are invoked by thePageMetaServicedirectly. The individual resolvers (resolveTitle,resolveRobots) no longer receive arguments, but use the localcart$observable to resolve the required data.-
CouponSearchPageResolverFindProductPageMetaResolver
Thewas introduced in version 1.5, and has been renamed toFindProductPageMetaResolverCouponSearchPageResolverin version 2.0.The deprecated
resolvemethod is removed in 2.0. This method is no longer supported because individual resolve methods (resolveTitle,resolveBreadcrumbs) are invoked by thePageMetaServicedirectly. The individual resolvers (resolveTitle,resolveBreadcrumbs) no longer receive arguments, but use the localtotal$observable to resolve the required data.The
scoremethod 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 dedicatedLoadWishListFailaction was added to maintain consistency in the wishlist. It is dispatched in the wishlist effects instead of theLoadCartFailaction. -
DeleteCartSuccess
TheDeleteCartSuccessaction was added to maintain consistency in the delete cart effect. It will be dispatched after DeleteCart action will successfully delete cart in backend. -
SetActiveCartId
TheSetActiveCartIdaction 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_IDconst,CartResetAddVoucheraction: we plan to migrate from the add voucher process to cart voucher eventsCartProcessesIncrementandCartProcessesDecrement: instead, extend EntityProcesses in actionsCartVoucherServicemethods:getAddVoucherResultError,getAddVoucherResultSuccess,getAddVoucherResultLoadingandresetAddVoucherProcessingState. 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
FormErrorscomponent 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
FormErrorscomponent uses translation keys from thecommonchunk. - 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). FormErrorsvisibility 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.LOADEDvalue was removed. ProfileTagEventService.addTrackernow 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:
cardsThis variable will no longer be in use. Use thecards$observable instead.goToThis variable will no longer be in use. Avoid using it.setAddressThis variable will no longer be in use. UseselectAddress(address: Address)instead.setAddressSubThis variable will no longer be in use. Avoid using it.selectedAddressSubThis variable will no longer be in use. Use theselectedAddress$observable instead.checkoutStepUrlNextThis variable will no longer be in use. UseCheckoutConfigService.getNextCheckoutStepUrl(this.activatedRoute)instead.checkoutStepUrlPreviousThis variable will no longer be in use. UseCheckoutConfigService.getPreviousCheckoutStepUrl(this.activatedRoute)instead.selectedAddressThis variable will no longer be in use. UseselectedAddress$observable instead.
Support for functions dropped:
addressSelectedThis method will no longer be in use. UseselectAddress(address: Address)instead.backThis method will no longer be in use. UsegoPrevious()instead.nextThis method will no longer be in use. UsegoNext()instead.addNewAddressThis method will no longer be in use. UseaddAddress(address: Address)instead.ngOnDestroyThis method will no longer be in use. Remove.