Skip to content

useProductsStore ​

The useProductsStore Pinia store manages product catalog data including products, categories, and brands. It provides centralized data fetching, localization transformation, initialization management, and utility methods for product-related operations.

Features ​

  • Product catalog management (products, categories, brands)
  • Localization transformation based on current language
  • Parallel data initialization with error handling
  • Thumbnail generation for product media

Usage ​

ts
import { useProductsStore } from '@/stores/products';

const productsStore = useProductsStore();

// Access reactive state
const { products, categories, brands, ready } = productsStore;

// Initialize store
await productsStore.init();

// Fetch specific data
const products = await productsStore.fetchProducts(['localizations', 'media']);
const categories = await productsStore.fetchCategories();
const brands = await productsStore.fetchBrands();

Properties ​

products ​

A ref containing the transformed product list.

  • Type: Ref<Product[]>
  • Default: Empty array
  • Features: Localized data, thumbnail URLs included

categories ​

A ref containing the transformed category list.

  • Type: Ref<Category[]>
  • Default: Empty array
  • Features: Localized names and data

brands ​

A ref containing the transformed brand list.

  • Type: Ref<Brand[]>
  • Default: Empty array
  • Features: Localized names and data

ready ​

A ref indicating whether all data has been successfully loaded.

  • Type: Ref<boolean>
  • Default: false
  • Logic: true when all parallel fetches succeed

initialized ​

A ref tracking whether the store has been initialized.

  • Type: Ref<boolean>
  • Default: false
  • Usage: Prevents duplicate initialization calls

Methods ​

Data Fetching ​

fetchProducts ​

ts
fetchProducts(fields?: ProductFieldsFilter[]): Promise<Product[]>

Fetches and transforms products from the API.

  • Parameters:
    • fields: Optional array of fields to include (default: ['localizations', 'media', 'prices'])
  • Returns: Promise resolving to transformed products array
  • Features: Automatic localization and thumbnail generation

fetchCategories ​

ts
fetchCategories(): Promise<Category[]>

Fetches and transforms categories from the API.

  • Returns: Promise resolving to localized categories array

fetchBrands ​

ts
fetchBrands(): Promise<Brand[]>

Fetches and transforms brands from the API.

  • Returns: Promise resolving to localized brands array

init ​

ts
init(): Promise<void>

Initializes the store by fetching all data in parallel.

  • Features:
    • Parallel API calls for performance
    • Error handling with logging
    • Sets ready state based on success
    • Prevents duplicate initialization
    • Detailed error logging for failed calls

reset ​

ts
reset(): void

Resets all store state to initial values.

  • Resets: products, categories, brands arrays and ready state

Utility Methods ​

getCategoryName ​

ts
getCategoryName(id: string): string

Gets category name by ID.

  • Parameters:
    • id: Category ID to look up
  • Returns: Category name or empty string if not found

getBrandName ​

ts
getBrandName(id: string): string

Gets brand name by ID.

  • Parameters:
    • id: Brand ID to look up
  • Returns: Brand name or empty string if not found

Transformation Methods ​

transformProducts ​

ts
transformProducts(products: Product[]): Product[]

Transforms products with localization and thumbnail generation.

  • Features:
    • Merges localized data for current language
    • Adds thumbnail URL from first media item
    • Handles missing data gracefully

transformCategories ​

ts
transformCategories(categories: Category[]): Category[]

Transforms categories with localization for current language.

transformBrands ​

ts
transformBrands(brands: Brand[]): Brand[]

Transforms brands with localization for current language.

Example ​

vue
<script setup lang="ts">
const productsStore = useProductsStore();
const { products, categories, brands, ready } = productsStore;

// Initialize on mount
onMounted(async () => {
  await productsStore.init();
  if (ready.value) {
    console.log(`Loaded ${products.value.length} products`);
  }
});

// Get category name for a product
const getProductCategoryName = (product: Product) => {
  return productsStore.getCategoryName(product.categoryId);
};

// Get brand name for a product
const getProductBrandName = (product: Product) => {
  return productsStore.getBrandName(product.brandId);
};

// Refresh products with specific fields
const refreshProducts = async () => {
  await productsStore.fetchProducts([
    'localizations',
    'media',
    'prices',
    'stock',
  ]);
};
</script>

<template>
  <div v-if="ready" class="product-catalog">
    <div v-for="product in products" :key="product._id" class="product-card">
      <img :src="product.thumbnail" :alt="product.name" />
      <h3>{{ product.name }}</h3>
      <p>Category: {{ getProductCategoryName(product) }}</p>
      <p>Brand: {{ getProductBrandName(product) }}</p>
    </div>
  </div>
  <div v-else class="loading">Loading product catalog...</div>
</template>

Type Definitions ​

ts
function useProductsStore(): ProductsStoreReturnType;

interface ProductsStoreReturnType {
  products: Ref<Product[]>;
  categories: Ref<Category[]>;
  brands: Ref<Brand[]>;
  ready: Ref<boolean>;
  fetchProducts: (fields?: ProductFieldsFilter[]) => Promise<Product[]>;
  fetchCategories: () => Promise<Category[]>;
  fetchBrands: () => Promise<Brand[]>;
  init: () => Promise<void>;
  reset: () => void;
  getCategoryName: (id: string) => string;
  getBrandName: (id: string) => string;
  transformProducts: (products: Product[]) => Product[];
}

type ProductFieldsFilter =
  | 'localizations'
  | 'media'
  | 'prices'
  | 'stock'
  | 'categories'
  | 'brands';

interface Product {
  _id: string;
  name: string;
  categoryId: string;
  brandId: string;
  thumbnail?: string;
  localizations?: Record<string, any>;
  media?: Media[];
  prices?: Price[];
  [key: string]: any;
}

interface Category {
  _id: string;
  name: string;
  localizations: Record<string, any>;
  [key: string]: any;
}

interface Brand {
  _id: string;
  name: string;
  localizations: Record<string, any>;
  [key: string]: any;
}

interface Media {
  _id: string;
  [key: string]: any;
}

Dependencies ​

This store depends on:

  1. Pinia: For store management
  2. useGeinsRepository: To access product API endpoints
  3. useAccountStore: For current language context
  4. useGeinsImage: For thumbnail URL generation
  5. useGeinsLog: For error logging and debugging
  6. #shared/types: For TypeScript type definitions