How to get reactive State on initial page load when using Fetch inside a Pinia Store #1078
-
Hi all, I'm trying to separate my business logic in a store ( import { ref } from 'vue'
import { defineStore } from 'pinia'
export const usePostsStore = defineStore('posts', () => {
const posts = ref([])
function getPosts() {
fetch('https://mywebsite.com/wp-json/wp/v2/posts')
.then(response => response.json())
.then(data => {
posts.value = data
console.log('Data is fetched.')
})
.catch((error) => {
console.log(error)
})
}
return {
posts,
getPosts
}
}) I then use this store inside a component where I want to show the posts fetched from the API like so: <template>
<ul>
<li
v-for="post in posts"
:key="post.id"
>
<p>{{ post.title.rendered }}</p>
</li>
</ul>
</template>
<script setup>
import { ref } from 'vue'
import { usePostsStore } from '~/stores/posts'
const store = usePostsStore()
const posts = ref(store.posts)
store.getPosts()
console.log(posts)
</script> I expected the posts to be shown on page load. The <script setup>
import { ref } from 'vue'
const posts = ref(null)
fetch('https://mywebsite.com/wp-json/wp/v2/posts')
.then(response => response.json())
.then(data => {
posts.value = data
console.log('Data is fetched.')
})
.catch((error) => {
console.log(error)
})
</script> But I would like to separate this logic in a Pinia store of course 🙂 Thanks in advance! |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 7 replies
-
I got this to work by structuring the store with an object containing export const usePostsStore = defineStore('settings', {
state: () => ({
posts: [],
}),
actions: {
async getPosts() {
const result = await fetch('https://mywebsite.com/wp-json/wp/v2/posts');
const data = await result.json();
this.posts = data;
},
},
}) |
Beta Was this translation helpful? Give feedback.
-
@markteekman You have access to full composition api in the store definition function. export const usePostsStore = defineStore('posts', () => {
const posts = ref([])
function getPosts() {
fetch('https://mywebsite.com/wp-json/wp/v2/posts')
.then(response => response.json())
.then(data => {
posts.value = data
console.log('Data is fetched.')
})
.catch((error) => {
console.log(error)
})
}
// Runs the very first time the store is used. i.e., when the store is initialized.
getPosts()
return {
posts,
getPosts
}
}) |
Beta Was this translation helpful? Give feedback.
-
In case anyone runs into a similar issue. I'm using Nuxt 3 and tried the approach in the selected answer but instead used async / await with my store and ran into some issues. I tried useFetch provided by Nuxt and it kept getting stuck in pending. To get past this I had to make another await call to export const useEnrollmentStore = defineStore('enrollment', () => {
// Plan Selection Data
const products = ref([])
const tier = ref(1)
// SETTERS
const setters = {
setTier: (newTier: number) => {
tier.value = newTier
},
}
// ACTIONS
async function fetchProducts() {
if (process.dev) {
console.log('FETCHING PRODUCTS')
}
const {data, execute} = await useFetch('/api/products', {method: "POST"})
await execute() // Need to manually call execute for some reason in this context
const { data: p } = data.value
products.value = p
}
onMounted(async () => {
await fetchProducts()
})
return { products, tier, ...setters }
}) |
Beta Was this translation helpful? Give feedback.
@markteekman You have access to full composition api in the store definition function.