Home
Wiki
Home
Wiki
  1. 3. Reusables
  • Back to home
  • 1. Themes
  • Vs Code
    • Getting Started
  • Kitchenware
    • Layout
      • New Layout
      • Legacy Layout
    • Components
      • Announcement
      • Banner Carousel
      • Banner With Products Carousel
      • Blog Category List
      • Blog List
      • Brand List
      • Brands Carousel
      • Breadcrumb
      • Call To Action
      • Cart
      • Categories List
      • Change Password
      • Checkout
      • Cookie Manager
      • Filter list
      • Footer
      • Forgot Password
      • Form
      • Hero Carousel
      • Icon Block
      • Invitation
      • Last Visited Products
      • Layout
      • Login
      • Map
      • Nav Bar
      • Offer
      • Product Attachments
      • Product Attributes
      • Product Documentation
      • Product Expected
      • Product Modal
      • Products Block
      • Products Carousel
      • Product Single
      • Profile
      • Quote
      • Register
      • Related Products
      • Search
      • Stores
      • Subscribe Newsletter
      • Text with Image
      • Top Bar
      • Video
    • Reusables
      • Getting Started
    • Assets
      • Getting Started
    • SDK
      • Products
        • _findProductsByCategory
        • _findProductsByIds
        • _findProductsByTitle
        • _findProductsByFilter
        • _findProductsByCriteria
        • _findProductsAndCalculate
        • _findProductsThenCalculate
        • _getProductAttributeSet
        • _setLastVisited
      • Categories
        • _findCategoryTreeById
        • _findCategoriesByIds
        • _findCategoryByAlias
        • _findCategoryTreeByAlias
        • _getCategoryContent
      • Collections
        • _getCollectionContent
        • _findCollectionsByIds
        • _findCollectionsByIdsThenCalculate
      • Brands
        • _getBrandContent
        • _findBrandsByIds
      • Cart
        • _addToCartMulti
        • _addToCart
        • _setCart
        • _clearCart
        • _setCartListener
        • _removeFromCart
        • _calculateCart
      • Checkout
        • _startCheckout
        • _updateCheckout
        • _completeCheckout
      • Shopping Lists
        • _getShoppingLists
        • _updateShoppingList
        • _createShoppingList
        • _deleteShoppingList
        • _getShoppingListByAlias
      • Navigation
        • _getFooterMenu
        • _getHeaderMenu
      • Users
        • _getUserById
      • Utils
        • _calculateCurrency
        • _getCurrencySymbol
        • _getCulture
        • _subscribeToNewsletter
        • _findUnitsByIds
  • Noir
    • 0. Introduction
    • 1. Structure
      • Overview
      • LayoutA.liquid
      • ComponentsList.liquid
      • Metas.liquid
      • CssVariables.liquid
      • Json.liquid
      • GoogleTagManager.liquid
      • StagingButton.liquid
    • 2. Components
      • Overview
      • Announcement
      • BannerCarousel
      • BlogCategoryList
      • BlogList
      • BrandList
      • Breadcrumb
      • Cart
      • CategoriesList
      • ChangePassword
      • Checkout
      • CookieManager
      • FilterList
      • Footer
      • ForgotPassword
      • Form
      • IconBlock
      • Invitation
      • LastVisitedProducts
      • Login
      • Map
      • NavBar
      • ProductAttachments
      • ProductAttributes
      • ProductComparison
      • ProductDocumentation
      • ProductMixList
      • ProductsBlock
      • ProductsCarousel
      • ProductSingle
      • Profile
      • Register
      • RelatedProducts
      • SingleBlog
      • Stores
      • TextWithImage
      • ThankYouPage
      • TopBar
      • Wishlist
    • 3. Reusables
      • Overview
      • Addresses
      • BillingRetail
      • AddressForm
      • AnnouncementModal
      • BackToTop
      • Company
      • General
      • Login
      • LoginModal
      • Orders
      • Payment
      • ProductAttachments
      • ProductAttributes
      • ProductComparisonButton
      • ProductComparisonFloatingButton
      • ProductGridItem
      • ProductListItem
      • ShoppingListsButton
      • ProductModal
      • ProfileInfo
      • PromptModal
      • Register
      • Shipping
      • ShoppingLists
      • ShoppingListsNavbar
      • Toast
      • Users
      • VariantContent
      • WishlistButton
      • Services
    • 4. Assets
      • Fonts
      • Images
      • Templates
      • Javascript
        • Overview
        • theme.js
      • Css / Scss
        • Overview
        • ThemeClasses
    • 5. SDK
      • Overview
      • LiquidGlobals
      • ServicesSDK
  1. 3. Reusables

Services

Purpose#

The Services reusable is the theme’s client-side service layer.
It exposes a global object servicesreusabledefault (defined in Reusables/Services/Default.js) that provides a consistent set of async functions for calling the storefront backend (/api/...) and coordinating cross-cutting behaviors like:
Standardized response normalization
Error logging
Request cancellation (Axios cancel tokens)
Updating Alpine stores (cart, checkout, modal) after successful calls
Auxiliary flows (file uploads, payment redirects/form submits, GA events)
This file is effectively the theme’s “SDK”. Components and reusables call servicesreusabledefault.*(...) instead of repeating raw axios/fetch calls.

Where it's rendered#

This reusable is typically rendered once in the layout, so the global object is available to all components.

Inputs (Liquid render parameters)#

This reusable is rendered without Liquid parameters.

Template behavior (Liquid + Alpine)#

This reusable does not render UI.
Its role is to register the global JavaScript object servicesreusabledefault, which is then consumed by other components and reusables.

JavaScript#

Standard function conventions#

1) Pattern: Axios + normalized return#

Most methods follow this structure:
1.
Call an endpoint using axios.get/post/put/delete.
2.
Normalize the response via:
getAxiosResponse(response, context)
3.
Return the normalized object:
4.
On exceptions:
Log with a method-specific console.error('<method> failed:', e)
Return e.response (raw Axios error response), or return the cancel error when using cancel tokens.

2) Context strings#

getAxiosResponse is always called with a stable context string (usually the method name), e.g.:
this.getAxiosResponse(response, 'addToCart')
This makes error logs searchable and consistent.

3) Cancellation#

Some methods cancel the previous request before starting a new one, using:
axios.CancelToken.source()
The service caches sources on:
servicesreusabledefault.cancelTokenSource
servicesreusabledefault.calculatecartCancelTokenSource

4) Side effects#

Several methods intentionally do more than “just call an API”. Common side effects include:
Updating localStorage (cartToken, checkoutToken, cartData)
Calling setCookie(...)
Updating Alpine stores:
Alpine.store('cart').update(...)
Alpine.store('checkout').set(...)
Alpine.store('checkout').validateStep(...)
Alpine.store('checkout').isUpdating = true/false
Alpine.store('modal').shouldReinitialize = true

5) fetch vs axios#

Some search endpoints use fetch(...) and return raw JSON (not the normalized wrapper). These are exceptions and are documented explicitly below.

API reference (grouped by category)#

General#

getAxiosResponse(response, context = "")#

Normalizes an Axios response into a stable shape.
Parameters:
response: Axios response object (or falsy).
context: optional string used in logs.
Behavior:
If response.status is not 2xx, logs a structured error and returns:
{ success: false, status, error: response }
If 2xx, returns:
{ success: true, status, data: response.data }

uuidv4()#

Generates a random GUID-like string using crypto.getRandomValues.
Used for:
checkoutToken generation
file upload session ids

setShopranosCookie(value, expiresAt)#

POST /api/cookies.
Parameters:
value: cookie value.
expiresAt: expiration date/time.
Returns:
normalized response via getAxiosResponse.

internalUploadFile(file, url, endpoint = null)#

Uploads a file in chunks (200000 bytes per chunk) using fetch and FormData.
Parameters:
file: a File object.
url: base upload URL.
endpoint: optional extra query param ?endpoint=....
Returns:
guid (string) for the upload session, or null on failure.
Notes:
Uses uuidv4() internally.
Does not use axios.

Shopping Lists#

getShoppingLists()#

GET /api/ShoppingList.
Side effects:
Alpine.store('modal').shouldReinitialize = true.
Returns normalized response.

createShoppingList(data)#

POST /api/ShoppingList.
Parameters:
data: request payload (shopping list creation model).
Returns normalized response.

deleteShoppingList(alias)#

DELETE /api/ShoppingList/{alias}.
Parameters:
alias: shopping list alias.
Returns normalized response.

updateShoppingList(list)#

PUT /api/ShoppingList/{list.alias}.
Parameters:
list: full list object; must include alias.
Returns normalized response.

importShoppingList(alias, file)#

Imports items into an existing list.
Steps:
1.
Uploads the file via internalUploadFile(file, '/api/file') → returns guid
2.
POST /api/ShoppingList/import-items/{alias}/{guid}
Parameters:
alias: list alias.
file: import file.
Returns normalized response.

exportShoppingList(alias)#

Exports items to a file.
POST /api/ShoppingList/export-items/{alias} with { responseType: 'blob' }.
Creates a browser download named ShoppingList-{alias}.xlsx.
Parameters:
alias: list alias.
Returns normalized response.

Wishlist#

clearWishlist()#

DELETE /api/wishlist/items.
Returns normalized response.

addItemToWishlist(productId)#

POST /api/wishlist/items/products/{productId}.
Parameters:
productId: product id.
Returns normalized response.

removeItemFromWishlist(productId)#

DELETE /api/wishlist/items/products/{productId}.
Parameters:
productId: product id.
Returns normalized response.

Navbar (Search + announcements)#

findProductsByCriteria(searchCriteria)#

Performs a product search using fetch.
Endpoint: GET /api/products/liquid with query string params.
Parameters:
searchCriteria: object of query params. Only non-null/undefined values are included.
Returns:
object | null
Returns parsed JSON on success.
Returns null and logs on non-OK response.

findProductsByCriteriaExtended(searchCriteria)#

Like findProductsByCriteria but uses:
GET /api/products/search-extended
Parameters:
searchCriteria: object of query params.
Returns:
parsed JSON.
Errors:
Throws an Error when the response is not OK.

setReadAnnouncementIds(ids)#

POST /api/announcements.
Parameters:
ids: array/payload containing announcement ids.
Returns normalized response.

Form#

sendEmail(data)#

Sends the contact form to the backend.
Uploads file fields first (where field.type == 4).
POST /api/contact.
Parameters:
data: contact form payload; expected to include fields[].
Returns normalized response.

internalUploadFiles(fields)#

Uploads contact form files for a set of form fields.
Parameters:
fields: list of field definitions.
Behavior:
Reads files from DOM input document.getElementById(field.name).files.
Uploads each file via uploadContactFormFile(file).
Writes back field.value as a comma-joined list of returned GUIDs.

uploadContactFormFile(file)#

Uploads a single contact-form file.
Calls internalUploadFile(file, '/api/file/contact').
Returns:
guid string or null.

Profile (Account, addresses, managed users)#

accountForgotPassword(data)#

POST /api/account/forgotpassword.
Parameters:
data: forgot password payload.
Returns normalized response.

changePassword(data)#

POST /api/account/changepassword.
Parameters:
data: change password payload.
Returns normalized response.

changePasswordProfile(data)#

POST /api/account/changeprofilepassword.
Parameters:
data: profile password change payload.
Returns normalized response.

updateUserProfile(data)#

PUT /api/account/updateuserinfo.
Parameters:
data: user profile payload.
Returns normalized response.

createUserAddress(data)#

POST /api/customer/addresses.
Parameters:
data: address payload.
Returns normalized response.

updateUserAddress(data, addressId)#

PUT /api/customer/addresses/{addressId}.
Parameters:
data: address payload.
addressId: address id.
Returns normalized response.

deleteUserAddress(addressId)#

DELETE /api/customer/addresses/{addressId}.
Parameters:
addressId: address id.
Returns normalized response.

setUserAddressAsPrimary(addressId)#

POST /api/customer/addresses/setdefault/{addressId}.
Parameters:
addressId: address id.
Returns normalized response.

accountLogin(data)#

POST /api/account/login.
Parameters:
data: login payload.
Side effects on success (status == 200):
GET /api/cart/user to retrieve a user cart.
Sets localStorage.cartToken, cookie cartToken, and localStorage.cartData.
Returns normalized response.

accountRegister(data)#

POST /api/account/register.
Parameters:
data: register payload.
Returns normalized response.

registerUser(data, token)#

POST /api/account/confirmInvitation/{token}.
Parameters:
data: registration payload.
token: invitation token.
Returns normalized response.

deleteUser(user)#

DELETE /api/managedusers/{user.id}.
Parameters:
user: object with at least id.
Returns normalized response.

updateUser(user)#

PUT /api/managedusers/{user.id}.
Parameters:
user: user object (must include id).
Returns normalized response.

inviteUser(data)#

POST /api/managedusers/invite.
Parameters:
data: invite payload.
Returns normalized response.

fetchUsers()#

GET /api/managedusers with params:
page: 1
pageSize: 12
Returns normalized response.

uploadCompanyLogo(file, customerId)#

Uploads a company logo.
Steps:
1.
Uploads the file via internalUploadFile(file, '/api/file', '/api/files/upload/logo/{customerId}')
2.
PUT /api/customer/logo
Parameters:
file: logo file.
customerId: customer id.
Returns normalized response.

deleteCompanyLogo()#

DELETE /api/customer/logo.
Returns normalized response.

Cart#

addToCart(productId, variantId, quantity, finalPrice, originalPrice, showPopUp = true)#

Adds a single item to the cart.
Endpoint:
POST /api/cart/{cartToken}/add
Parameters:
productId: product id.
variantId: product variant id.
quantity: quantity to add.
finalPrice: used for GA payload (price).
originalPrice: used for GA payload (initialPrice).
showPopUp: passed to $store.cart.update(...) to control UI feedback.
Preconditions / side effects:
Cancels previous cart update via cancelTokenSource.
Ensures localStorage.checkoutToken exists (creates one via uuidv4() and sets cookie checkoutToken).
Updates localStorage.cartToken + cookie cartToken.
If $store.cart exists, calls:
Alpine.store('cart').update(cartData, [{ ...addedItem, addedQuantity: quantity }], showPopUp)
If cart has items, sends GA event addToCart.
Returns normalized response.

addMultipleToCart(variations, showPopUp = true)#

Adds multiple items to cart in one request.
Endpoint:
POST /api/cart/{cartToken}/addmultiple
Parameters:
variations: array of objects with at least:
productId
productVariantId
quantity
dim1Value, dim2Value
price, initialPrice
showPopUp: passed to cart store update.
Side effects:
Updates token/cookie.
Updates $store.cart once with successfully added products.
Sends GA addToCart event.
Returns normalized response.

updateProductCart(cartData, cancelToken)#

Updates the cart.
Endpoint:
PUT /api/cart/{cartToken}
Parameters:
cartData: cart update payload.
cancelToken: Axios cancel token.
Side effects:
Updates token/cookie.
Calls Alpine.store('cart').update(cartData).
Returns normalized response (or cancel error).

updateProductQuantity(data, cancelToken)#

Validates/resolves requested quantity.
Endpoint:
POST /api/cart/{cartToken}/resolveQuantity
Parameters:
data: object with:
productId
productVariantId
requestedQuantity
cancelToken: Axios cancel token.
Returns normalized response (or cancel error).

clearCart()#

Clears all cart items.
Endpoint:
DELETE /api/cart/{cartToken}/all
Side effects:
Sends GA removeFromCart based on stored localStorage.cartData.
Updates token/cookie.
Calls Alpine.store('cart').update(cartData).
Returns normalized response.

removeFromCart(variantId)#

Removes an item by variant id.
Endpoint:
DELETE /api/cart/{cartToken}/{variantId}
Parameters:
variantId: product variant id.
Side effects:
Sends GA removeFromCart for the removed line.
Updates token/cookie.
Calls Alpine.store('cart').update(cartData).
Returns normalized response.

getCartValidation()#

Fetches calculated cart validation and returns a simplified error summary.
Endpoint:
GET /api/cart/calculated/{cartToken}/
Cancellation:
Cancels the previous calculation request using calculatecartCancelTokenSource.
Returns:
On success: { isSuccess, lines: [{ type, count, lineIds[] }] }
On failure: returns e.response.

Checkout#

updateCheckout(data, checkoutStep = null)#

Updates checkout.
Endpoint:
POST /api/checkout/update/{checkoutToken}
Parameters:
data: checkout update payload.
checkoutStep: optional string; when present, triggers step validation.
Side effects:
Injects data.cartItems = Alpine.store('cart').items.
Toggles Alpine.store('checkout').isUpdating.
On success:
Alpine.store('checkout').set(returnResponse.data)
Alpine.store('checkout').validateStep(checkoutStep, true)
On error:
Alpine.store('checkout').globalError = true
validateStep(checkoutStep, false)
Returns normalized response.

proceedToCheckout(data)#

High-level checkout continuation.
Behavior:
Calls updateCheckout(data).
If there is a payment provider, calls initiatePayment(checkoutData).
Otherwise calls completeCheckout().
Returns normalized response.

initiatePayment(data)#

Initiates payment and performs provider-specific redirects.
Endpoint:
POST /api/payment/initiate/{checkoutToken}
Parameters:
data: checkout data; must contain data.payment.provider.
Behavior:
Redirects the browser when redirectUrl is returned for providers like PayPal/JCC/Stripe/Nexi.
Builds and auto-submits provider forms for EDPS/Epay/CardLink.
Injects and executes HTML snippet for Klarna.
Otherwise falls back to completeCheckout().
On errors:
Redirects to /checkout/error.

completeCheckout()#

Completes checkout.
POST /api/checkout/complete/{checkoutToken}.
Returns normalized response.

fetchPostalCodes(countryCode)#

Fetches postal codes.
GET /api/location/postalcodes/{countryCode}.
Parameters:
countryCode: country code.
Returns normalized response.

Thank You#

triggerOrderViewedCleanup(orderId)#

Triggers analytics cleanup after the thank-you page is viewed.
POST /api/order/{orderId}/analytics/thank-you-page-viewed
Parameters:
orderId: order id.
Returns normalized response.

Global Alpine stores#

This reusable may update these stores when they exist (depending on the called method):
$store.cart
$store.checkout
$store.modal
$store.toast (indirectly; most callers handle toasts themselves)

Services / API calls#

This reusable is the services layer itself.
It calls backend endpoints under /api/... via axios (mostly) and fetch (in specific search endpoints).

Dependencies#

JS: Reusables/Services/Default.js
Translations: Reusables/Services/Default.json

Notes#

servicesreusabledefault includes both:
“thin” API wrappers (call endpoint + normalize)
“orchestrators” that update stores/local storage and trigger GA events.
Modified at 2026-04-14 13:18:56
Previous
WishlistButton
Next
Fonts
Built with