JAVASCRIPT
Map API Response to a Consistent Frontend Model
Learn to transform raw API response data into a clean, consistent frontend model, improving data predictability and reducing coupling between UI and API changes.
// Define a simplified frontend model structure
class Product {
constructor({ id, name, price, description, imageUrl, stockAmount }) {
this.id = id;
this.name = name;
this.price = parseFloat(price).toFixed(2); // Ensure price is always 2 decimal places
this.description = description || 'No description available.';
this.imageUrl = imageUrl || 'https://via.placeholder.com/150';
this.inStock = stockAmount > 0;
this.displayPrice = `$${this.price}`;
}
// Add any display logic or helper methods here
getShortDescription(maxLength = 100) {
return this.description.length > maxLength
? `${this.description.substring(0, maxLength)}...`
: this.description;
}
}
/**
* Transforms a raw API product object into a consistent Product frontend model.
* Handles potential inconsistencies or different naming conventions from various APIs.
* @param {Object} apiProduct - The raw product object from an API.
* @returns {Product} A new Product instance.
*/
function transformApiProduct(apiProduct) {
if (!apiProduct) {
return null;
}
// Map potentially different API field names to our model's field names
const mappedData = {
id: apiProduct.productId || apiProduct.id,
name: apiProduct.productName || apiProduct.name,
price: apiProduct.currentPrice || apiProduct.price,
description: apiProduct.details || apiProduct.description,
imageUrl: apiProduct.imageLink || apiProduct.thumbnailUrl || apiProduct.imageUrl,
stockAmount: apiProduct.availableStock || apiProduct.inventoryCount || 0,
};
// Create an instance of our Product class
return new Product(mappedData);
}
// Example Usage:
// const rawApiProduct1 = {
// productId: 'p001',
// productName: 'Super Widget',
// currentPrice: '29.99',
// details: 'A truly super widget for all your needs.',
// imageLink: 'https://example.com/widget.jpg',
// availableStock: 10
// };
// const rawApiProduct2 = { // From a different API with different naming
// id: 'p002',
// name: 'Mega Gadget',
// price: 99.99,
// description: 'An advanced gadget with many features.',
// thumbnailUrl: 'https://example.com/gadget.png',
// inventoryCount: 0
// };
// const transformedProduct1 = transformApiProduct(rawApiProduct1);
// const transformedProduct2 = transformApiProduct(rawApiProduct2);
// console.log('Transformed Product 1:', transformedProduct1);
// console.log('Is Product 1 in stock?', transformedProduct1.inStock);
// console.log('Transformed Product 2:', transformedProduct2);
// console.log('Is Product 2 in stock?', transformedProduct2.inStock);
// console.log('Product 2 short description:', transformedProduct2.getShortDescription(20));
How it works: This snippet illustrates a common pattern for transforming inconsistent or verbose API response data into a clean, predictable frontend data model. It defines a `Product` class to represent the desired structure and a `transformApiProduct` function. This function takes a raw API object and maps its fields (handling different potential naming conventions like `productId` vs `id`) to the `Product` class's constructor. This approach decouples the frontend UI from direct API schema changes, adds computed properties (`inStock`, `displayPrice`), and centralizes data normalization, making the application more robust and easier to maintain.