Best practices for usage within Pinia actions #458
-
I was looking for some guidance on the best approach for creating reusable mutations by using Pinia actions. I'm fairly new to both Composition API and TypeScript so I'm still figuring out the best way to go about implementing things, but any advice would be super helpful! I've put together some reduced examples of my use case, hopefully it makes sense. Ideally I'd like to use something like Approach A, but I'm facing some issues with the types, so maybe this is more a TS question. Approach AAction returns // stores/account.ts
import { defineStore } from 'pinia'
import type { Ref } from 'vue'
import type {
CustomerAccessToken,
CustomerAccessTokenCreateInput,
CustomerAccessTokenCreateMutation,
CustomerAccessTokenCreateMutationVariables,
CustomerFragment,
} from '@/shopify-types'
import { CustomerAccessTokenCreateDocument } from '@/graphql/exports'
interface State {
customer: CustomerFragment | null
customerAccessToken: string | null
}
export const useAccountStore = defineStore('account', {
state: (): State => ({
customer: null,
customerAccessToken: null,
}),
actions: {
createCustomerAccessToken(input: Ref<CustomerAccessTokenCreateInput>) {
const mutation = useMutation<
CustomerAccessTokenCreateMutation,
CustomerAccessTokenCreateMutationVariables
>(CustomerAccessTokenCreateDocument, () => ({
variables: {
input: unref(input)
},
}))
mutation.onDone(({ data }) => {
// set customerAccessToken in store
})
return mutation
},
},
}) <template>
<form :disabled="loading" @submit.prevent="mutate">
// ...
</form>
</template>
<script lang="ts" setup>
import { useAccountStore } from '@/stores/account'
const authFields = ref({
email: '',
password: '',
})
const { mutate, loading } = createCustomerAccessToken(authFields)
</script> Caveats
Approach BSimilar to how I handled mutations in Nuxt 2, with the action returning the import { defineStore } from 'pinia'
import type {
CustomerAccessToken,
CustomerAccessTokenCreateInput,
CustomerAccessTokenCreateMutation,
CustomerAccessTokenCreateMutationVariables,
CustomerFragment,
} from '@/shopify-types'
import { CustomerAccessTokenCreateDocument } from '@/graphql/exports'
interface State {
customer: CustomerFragment | null
customerAccessToken: string | null
}
export const useAccountStore = defineStore('account', {
state: (): State => ({
customer: null,
customerAccessToken: null,
}),
actions: {
createCustomerAccessToken(input: CustomerAccessTokenCreateInput) {
const { mutate, onDone } = useMutation<
CustomerAccessTokenCreateMutation,
CustomerAccessTokenCreateMutationVariables
>(CustomerAccessTokenCreateDocument, () => ({
variables: { input },
}))
onDone(({ data }) => {
// set customerAccessToken in store
})
return mutate()
},
},
}) <template>
<form :disabled="loading" @submit.prevent="onSubmit">
// ...
</form>
</template>
<script lang="ts" setup>
import { useAccountStore } from '@/stores/account'
const { createCustomerAccessToken } = useAccountStore()
let loading = $ref(false)
const authFields = $ref({
email: '',
password: '',
})
async function onSubmit() {
loading = true
await createCustomerAccessToken(authFields).then(() => {
loading = false
})
}
</script> Caveats
|
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
After playing around with this more I've realised Approach B is the way to go, here's an example for anyone else who needs help on this (using Setup store syntax): import { defineStore } from 'pinia'
import type {
CustomerAccessTokenCreateMutation,
CustomerAccessTokenCreateMutationVariables,
CustomerFragment,
} from '@/shopify-types'
import { CustomerAccessTokenCreateDocument } from '@/graphql/exports'
export const useAccountStore = defineStore('account', () => {
const config = useRuntimeConfig()
let customer: CustomerFragment | null = ref(null)
let customerAccessToken: string = ref('')
function createCustomerAccessToken(
variables: CustomerAccessTokenCreateMutationVariables,
) {
const { mutate, onDone } = useMutation<CustomerAccessTokenCreateMutation>(
CustomerAccessTokenCreateDocument,
)
onDone(({ data }) => {
// set customerAccessToken in store/cookie
})
return mutate(variables)
}
return {
customer,
customerAccessToken,
createCustomerAccessToken,
}
}) |
Beta Was this translation helpful? Give feedback.
After playing around with this more I've realised Approach B is the way to go, here's an example for anyone else who needs help on this (using Setup store syntax):