0

I try the new composition api.

composable function useProdcut.js:

export default function useProduct() {
     const product = reactive({});
    
   async function getProduct(id) {
     try{ 
       const response = await {{http Request}}
       product.value = response.data; // it is a single object
     }catch(err) {
       console.log(err);
     }
   } 
    return {product, getProduct}
}

In my component I use two composable functions:

setup(_, {root}) {
…
const { product, getProduct} = useProduct();

const {productAlias, productTitle, createdAt, …} = useProductDetails(prodcut);

onBeforeMount(async () => {
loading.value = true;
await getProduct(root.$route.params.id);
loading.value = false;
});

return {loading, product, productAlias, …}
}

In useProductDetails.js I got the message:

product.value is undefined.

I think this is because of the value for product is retrieved in onBeforeMount. But how can I achieve to pass the product ref with value after mounted? Or is there an other way?

I appreciate any help. Thank you!

User 28
  • 4,863
  • 1
  • 20
  • 35
marciado
  • 41
  • 4
  • Could you post more code about `useProduct`? What does it return? Is `product` a ref? – User 28 Nov 16 '21 at 11:34
  • I edit the post & add more information update the function. Yes product is a reactive object – marciado Nov 16 '21 at 11:47
  • @User28 this is right or? – marciado Nov 16 '21 at 12:01
  • From `const product = reactive({})` it should be `ref` not `reactive`. – User 28 Nov 16 '21 at 12:15
  • And you have to keep in mind that `product` is a reactive object (ref) you have to use it via `watcher`, `computed` not just get its value and return. – User 28 Nov 16 '21 at 12:20
  • oh thank you very much!! I have to use ref instead of reactive & I had one function that was not a computed prop or run within a watcher. This solved it, thanks! @User28 – marciado Nov 16 '21 at 13:16
  • Glad to hear that. I suggest you try to post an answer of your question to better understand your code. – User 28 Nov 16 '21 at 13:26
  • yes makes sense! But can you explain to me why I need to use ref instead of reactive? I thought for primitive values I have to use ref and for objects I use reactive? – marciado Nov 16 '21 at 13:34
  • Actually, you can use `reactive` if you don't reassign the entire object. If you reassign `product` to `response.data` which is the new object so it no longer references the old reactive object anymore. See more https://stackoverflow.com/a/65262638/2438933. – User 28 Nov 16 '21 at 13:44

2 Answers2

2
const product = reactive({});

product shuld be ref and not reactive, because I reassign the entire object.

When product is reassigned to response.data which is the new object so it no longer references the old reactive object anymore. See more here.

marciado
  • 41
  • 4
1

When you're using reactive you don't have .value but if you use ref you the value is inside .value. So your composable must be like:

export default function useProduct() {
     const product = ref();
    
   async function getProduct(id) {
     try{ 
       const response = await {{http Request}}
       product.value = response.data; // it is a single object
     }catch(err) {
       console.log(err);
     }
   } 
    return {product, getProduct}
}

If you use Nuxt 3, you must use useState instead of ref doc

Farid
  • 170
  • 1
  • 6