'Pinia w/ Vue3: Using Actions in template returns funcName is not a function
Using a Pinia action from within the template in Vue3 gives
Uncaught TypeError: $setup.[storeName].[actionName] is not a function
Am I doing something wrong or is it expected behaviour. It doesn't seem that anybody else having the same issue. Google search didn't reveal anything.
I'm using the new components
Solution 1:[1]
I ran into this when I mistakenly tried to destructure actions as well as state and getters with storeToRefs
, after not reading this bit from the Pinia docs carefully enough:
In order to extract properties from the store while keeping its reactivity, you need to use
storeToRefs()
. It will create refs for every reactive property. This is useful when you are only using state from the store but not calling any action. Note you can destructure actions directly from the store [emphasis added] as they are bound to the store itself too.
So given this template —
<template>
<ul>
<li v-for="thing in things" :key="thing">{{ frob(thing) }}</li>
<li>
</template>
— and this store —
const useStore = defineStore("store", {
state: () => ({ things: ["1", "2", "3"], }),
actions: { frob(arg) { return `frobbed ${arg}`; } },
});
const store = useStore();
— if you try to destructure both things
and frob
with storeToRefs
, you'll get TypeError: $setup.frob is not a function
. Actions, unlike state and getters, should be destructured directly from the store object:
// wrong
const { things, frob } = storeToRefs(store);
// right
const { things } = storeToRefs(store)
const { frob } = store
Note that in Chrome the error will show up as Uncaught (in promise)
, while in Safari it will show up as Unhandled Promise Rejection
.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | David Moles |