Add or update cartline(s)
Cart Action
Header
- Composable Action:
composables/useCart/useCartApi.ts - API Route:
PUT /api/carts/[cartId]/cartlines/add
Detailed Description
The addOrUpdateCartLines action is an essential feature of the cart system that allows adding or
updating products in the cart. It plays a central role in cart management by enabling users to:
- Add new products to the cart
- Update quantities of existing products
- Handle bulk modifications
This action is used in several contexts:
- Cart user interface
- Quick order process
- Synchronization between different carts
- Automatic stock updates
Process Flow
sequenceDiagram
participant U as User
participant C as Vue Component
participant UC as useCart
participant S as Pinia Store
participant A as API
participant Auth as Auth Service
U->>C: Add/Modify product
C->>UC: addOrUpdateCartLine(params)
UC->>Auth: Check authentication
Auth-->>UC: OK
UC->>A: PUT /api/carts/[cartId]/cartlines/add
A-->>UC: Response
UC->>S: Update store
S-->>C: State updated
C-->>U: UI updated
alt Authentication Error
Auth-->>UC: 401 Unauthorized
UC-->>C: Error
C-->>U: Login redirect
else Validation Error
A-->>UC: 400 Bad Request
UC-->>C: Error
C-->>U: Error message
else Stock Error
A-->>UC: 412 Precondition Failed
UC-->>C: Error
C-->>U: Insufficient stock message
end
Call Parameters
Main Interface
interface AddOrUpdateCartLineRequest {
cartId: string; // Cart ID
typeId: string; // Identifier type ('offerPriceId' or 'productVariantId')
currency: string; // Currency
lines: Array<{
// Lines to add/update
variantId?: string; // Variant ID (if typeId = 'productVariantId')
offerPriceId?: string; // Offer ID (if typeId = 'offerPriceId')
quantity: number; // Quantity
updateAction: UpdateCartLineType; // Update type
}>;
}Update Types
type UpdateCartLineType =
| 'ADD_QUANTITY' // Add specified quantity
| 'REMOVE_QUANTITY' // Remove specified quantity
| 'REPLACE_QUANTITY'; // Replace existing quantityDetailed Parameters
| Parameter | Type | Required | Default Value | Impact |
|---|---|---|---|---|
| cartId | string | Yes | - | Identifies the cart to modify |
| typeId | string | Yes | - | Determines the identifier type to use |
| currency | string | Yes | - | Currency for price calculations |
| lines | Array | Yes | - | List of modifications to apply |
| variantId | string | Conditional | - | Variant ID (if typeId = 'productVariantId') |
| offerPriceId | string | Conditional | - | Offer ID (if typeId = 'offerPriceId') |
| quantity | number | Yes | - | Quantity to add/modify |
| updateAction | UpdateCartLineType | Yes | - | Type of modification to apply |
Call Example
const response = await addOrUpdateCartLine({
cartId: 'cart-123',
typeId: 'offerPriceId',
currency: 'EUR',
lines: [
{
offerPriceId: 'offer-456',
quantity: 2,
updateAction: 'REPLACE_QUANTITY',
},
],
});Composable Returns
Response Interface
interface UpdateCartLinesResponse {
success: boolean; // Indicates if the update was successful
message: string; // Confirmation or error message
cartLines?: CartLine[]; // Updated lines
}
interface CartLine {
id: string; // Line ID
offerPriceId: string; // Offer ID
quantity: number; // Updated quantity
price: {
// Offer price
amount: number; // Amount
currency: string; // Currency
};
}Success Response Format
{
"success": true,
"message": "Cart lines added or updated successfully",
"cartLines": [
{
"id": "line-123",
"offerPriceId": "offer-456",
"quantity": 2,
"price": {
"amount": 19.99,
"currency": "EUR"
}
}
]
}Error Handling
Error Types
| Code | Cause | Action | Message |
|---|---|---|---|
| 401 | Not authenticated | Login redirect | "Not authenticated" |
| 400 | Invalid data | Error message | "Invalid data" |
| 404 | Cart not found | Carts redirect | "Cart not found" |
| 412 | Insufficient stock | Error message | "Insufficient stock" |
| 500 | Server error | Error message | "Server error" |
Error Response Format
{
"success": false,
"message": "Specific error message",
"error": {
"statusCode": 400,
"message": "Error details"
}
}Error Handling Example
try {
const response = await addOrUpdateCartLine({
cartId: 'cart-123',
typeId: 'offerPriceId',
currency: 'EUR',
lines: [
{
offerPriceId: 'offer-456',
quantity: 2,
updateAction: 'REPLACE_QUANTITY',
},
],
});
} catch (error) {
switch (error.statusCode) {
case 401:
router.push('/auth/login');
break;
case 404:
router.push('/carts');
break;
case 400:
showNotification('Invalid data', 'error');
break;
case 412:
showNotification('Insufficient stock', 'error');
break;
default:
showNotification('An error occurred', 'error');
}
}Use Cases
-
Product Addition
- Adding a new product to the cart
- Adding multiple products in a single operation
- Managing initial quantities
-
Product Updates
- Modifying existing quantities
- Bulk updating multiple products
- Stock synchronization
-
Variant Management
- Adding products by variant
- Updating existing variants
- Managing stock by variant
Important Points
Performance
- Optimized Pinia store updates
- Efficient error handling
- Response caching
Security
- Authentication verification
- Data validation
- Injection protection
Flexibility
- Support for different identifier types
- Error case handling
- Business needs adaptation
Integration
- Compatible with existing cart system
- Authentication system integration
- Notification system support
Technical Implementation
/**
* Adds or updates lines in the cart
* @param params - Request parameters
* @param params.cartId - Cart ID
* @param params.typeId - Identifier type ('offerPriceId' or 'productVariantId')
* @param params.currency - Currency
* @param params.lines - Lines to add/update
* @param useStore - If true, updates the Pinia store
* @returns Promise<UpdateCartLinesResponse | null>
* @throws {ApiError} - Error if request fails
*/
export const useCart = () => {
const addOrUpdateCartLine = async (
params: AddOrUpdateCartLineRequest,
useStore = true
): Promise<UpdateCartLinesResponse | null> => {
try {
await ensureAuthenticated();
const { data, error } = await useFetch<UpdateCartLinesResponse>(
`/api/carts/${params.cartId}/cartlines/add`,
{
method: 'PUT',
body: params,
key: `addOrUpdateCartLine-${params.cartId}`,
}
);
if (error.value) {
handleError(error.value);
}
if (useStore && data.value) {
updateStore(data.value);
}
return data.value || null;
} catch (e) {
handleError(e);
}
};
return {
addOrUpdateCartLine,
};
};Execution Flow
- Authentication Check
await ensureAuthenticated();- Parameter Validation
if (!params.cartId || !params.typeId || !params.lines?.length) {
throw new Error('Invalid parameters');
}- API Call
const { data, error } = await useFetch<UpdateCartLinesResponse>(
`/api/carts/${params.cartId}/cartlines/add`,
{
method: 'PUT',
body: params,
}
);- Response Handling
if (useStore && data.value) {
cartStore.cartLines = data.value.cartLines;
}- Error Handling
if (error.value) {
handleError(error.value);
}Updated 3 months ago
