'How to fetch data from API in vuex
I want to use vuex to store some data fetched from the server that my SPA Vue app will need in different pages, this to avoid that a new ajax request is made every time that the user will change product page (it's an headless ecommerce).
My question is simple, how I can push the fetched data into an array that is defined in my store? How I will get the data in my components? I'm writing the code but not sure if I've done it well.
import { createStore } from 'vuex'
import axios from 'axios'
export default createStore({
state: {
products: []
},
mutations: {
updateProductsData(state, products){
// not sure how to proceed here
}
},
actions: {
fetchProducts(){
const baseURL = 'https://www.example.com/app/index.php/wp-json/shop/v1/products';
let productsData = [];
axios.get(baseURL).then( response => {
response.data.forEach( el => {
console.log(el);
let details = {
id: el.id,
slug: el.slug,
name: el.name,
price: el.price,
description: el.description,
short_description: el.short_description
}
productsData.push(details);
});
store.commit('updateProductsData', productsData);
}).catch( e => console.log(e) );
}
}
})
In my components where I need to load the data I have this code
export default {
name: 'Home',
data(){
return {
loaded: false,
offers: [],
}
},
created(){
},
mounted(){
this.$store.dispatch('fetchProducts').then( res => this.offers.push(res) )
},
}
Solution 1:[1]
Inside your updateProductsData mutation use state.products = [...products] to add your loaded products to your state
Check https://www.vuemastery.com/courses/vuex-fundamentals/vuex4-intro-to-vuex for a short intro to Vuex
Solution 2:[2]
You can refer to the doc of Vuex about the use of actions and mutations https://vuex.vuejs.org/guide/actions.html . It's detailed...
As Vuex suggests, you should put async operations in actions (like fetching data from the server in your example). Then you should commit a "mutation" to use the fetched data to set your state like the code given below
import { createStore } from 'vuex'
import axios from 'axios'
export default createStore({
state: {
products: []
},
mutations: {
updateProductsData(state, products){
// here set your state
state.products = products
}
},
actions: {
fetchProducts({commit}){
const baseURL = 'https://www.example.com/app/index.php/wp-json/shop/v1/products';
let productsData = [];
axios.get(baseURL).then( response => {
response.data.forEach( el => {
console.log(el);
let details = {
id: el.id,
slug: el.slug,
name: el.name,
price: el.price,
description: el.description,
short_description: el.short_description
}
productsData.push(details);
});
store.commit('updateProductsData', productsData);
}).catch( e => console.log(e) );
}
}
})
If you want to use the state in your components, you can put it in computed attribute.
export default {
name: 'Home',
data(){
return {
loaded: false,
}
},
computed:{
// map this.offers to store.state.products
offers(){
return this.$store.state.products
}
},
created(){
},
mounted(){
// dispatch 'fetchProducts' to fetch data
this.$store.dispatch('fetchProducts')
},
}
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 | andreasbecker.de |
| Solution 2 |
