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
      • Quote
      • Register
      • RelatedProducts
      • SingleBlog
      • Stores
      • TextWithImage
      • ThankYouPage
      • TopBar
      • Wishlist
    • 3. Reusables
      • _Overview
      • Addresses
      • BillingRetail
      • AddressForm
      • AnnouncementModal
      • BackToTop
      • Company
      • General
      • Login
      • LoginModal
      • MonthlyTransactions
      • Orders
      • Payment
      • ProductAttachments
      • ProductAttributes
      • ProductComparisonButton
      • ProductComparisonFloatingButton
      • ProductGridItem
      • ProductListItem
      • ProductModal
      • ProfileInfo
      • PromptModal
      • Register
      • Services
      • Shipping
      • ShoppingLists
      • ShoppingListsButton
      • ShoppingListsNavbar
      • Toast
      • Transactions
      • Users
      • VariantContent
      • WishlistButton
      • Quotes
    • 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 methods on servicesreusabledefault instead of repeating raw axios/fetch calls.
Note: this documentation refers to specific methods by name (for example servicesreusabledefault.getShoppingLists()). Avoid using wildcard references like “all methods on servicesreusabledefault”, because the docs audit may treat them as tokens.

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 Axios CancelToken sources on internal properties of the services object.

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-05-04 12:18:01
Previous
Register
Next
Shipping
Built with