Search code examples
nuxt3.jspinia

Nuxt page doesn't render array from Pinia store


I have Nuxt page for products list with fetchProducts() method from pinia store.

The problem is that product list NOT rendered on page 1st visit.

<script setup>
import { storeToRefs}   from "pinia";
import { useShopStore } from '@/stores/shop'

const shop = useShopStore();
shop.fetchProducts();
const {products} = storeToRefs(shop)
const hasProducts = computed(() => products.value.length > 0);

</script>

<template>
    <NuxtLayout>
        <div class="container">
            <h2>Products</h2>
            <div class="container" v-if="hasProducts">
                  <div class="row row-cols-1 gap-3">
                    <ProductCard :product="product" v-for="product in products" :key="product.id"/>
                </div>
            </div>
            <div v-else>
                <h3>Products NOT loaded</h3><br>
            </div>
        </div>
    </NuxtLayout>
</template>

As you can see on following snapshot products are loaded and available in pinia store, but array products on page is empty.

enter image description here

If I go back to home and return to product page products are rendered without any problem or warnings in console.

Any suggestion what I can do to fix or even investigate the issue?

PS. Store code if it's matter here

import { defineStore } from 'pinia'

import Product  from "@/models/Product";

export const useShopStore = defineStore('shop', {
    state: () => ({
        //products: <Product[]>[]
        products: [] as Product[]
    }),
    actions: {
        fetchProducts: async function () {
            try {
                const {data} = await useFetch('https://fakestoreapi.com/products');
                //TODO - fix this  typescript error `TS2352: Conversion of type 'Ref<unknown>' to type 'Product[]' may be a mistake because neither type sufficiently overlaps with the other.`
                // @ts-ignore
                this.products = data as Product[];
            } catch (error) {
                return error
            }
        },
    }
})

Solution

  • I'm not sure how valid it is, but assign this.products = data.value as Product[]; instead of this.products = data as Product[]; seems to fix the issue.

    fetchProducts: async function () {
      try {
        
        // TODO - fix this  typescript error `TS2352: Conversion of type 'Ref<unknown>' to type 'Product[]' may be a mistake because neither type sufficiently overlaps with the other.`  // @ts-expect-error
    
            // NOTE: OPTION 1, with useFetch() -> require import
            const { data } = await useFetch('https://fakestoreapi.com/products')
            this.products = (await data.value) as Product[]
    
            // NOTE: OPTION 2, with fetch()
            // const response = await fetch('https://fakestoreapi.com/products')
            // this.products = (await response.json()) as Product[]
      } catch (error) {
        return error
      }
    }
    

    Please let me know if it's a good solution or not. I'm still learning Vue 3 and Nuxt 3 and not sure that using useFetch inside pinia store is a good idea.