Reputation: 897
I have data taken from API laravel, and here is my code in state.js
import axios from 'axios'
import {apiPostGet} from '../api/api'
export default {
data: axios({
method: 'GET',
url: apiPostGet('Kategori')
}).then(
response => {
return response.data.kategori
}
).catch(
error => {
return error.response
}
)
}
and this is my code in gteeters.js
export default {
datas: state => {
return state.data
}
}
and this is my code in index.js
import Vue from 'vue'
import Vuex from 'vuex'
import state from './state'
import getters from './getters'
Vue.use(Vuex)
export default new Vuex.Store({
state,
getters
})
Upvotes: 15
Views: 32274
Reputation: 5460
I would use the solution of the AWolf, however with a slightly improved error handling in the loadData method
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
function getUrlParams() {
var url_params = new URLSearchParams();
if (window.location.toString().indexOf("?") != -1) {
var href_part = window.location.search.split('?')[1]
href_part.replace(/([^=&]+)=([^&]*)/g,
function(m, key, value) {
var attr = decodeURIComponent(key)
var val = decodeURIComponent(value)
url_params.append(attr, val);
});
}
// for(var pair of url_params.entries()) { consolas.log(pair[0]+ '->'+ pair[1]); }
return url_params;
}
function getServerData(url, urlParams) {
if (typeof url_params == "undefined") {
urlParams = getUrlParams()
}
return axios.get(url, {
params: urlParams
})
.then(response => {
return response;
})
.catch(function(error) {
console.error(error)
return error.response;
})
}
// Action !!!
getServerData(url, url_params)
.then(response => {
if (response.status === 204) {
var warningMsg = response.statusText
console.warn(warningMsg)
return
} else if (response.status === 404 || response.status === 400) {
var errorMsg = response.statusText // + ": " + response.data.msg // this is my api
console.error(errorMsg)
return;
} else {
var data = response.data
var dataType = (typeof data)
if (dataType === 'undefined') {
var msg = 'unexpected error occurred while fetching data !!!'
// pass here to the ui change method the msg aka
// showMyMsg ( msg , "error")
} else {
var items = data.dat // obs this is my api aka "dat" attribute - that is whatever happens to be your json key to get the data from
// call here the ui building method
// BuildList ( items )
}
return
}
})
</script>
Upvotes: 0
Reputation: 8990
Data
hook needs to return synchronously. You have to add the loading to created
or mounted
and just add the properties to data / state, so reactivity is working.
The loading of the data with Axios needs to be triggerd with an action because it's asynch. Mutations need to run synchronous. I've added the initial loading in created
. (mounted
would also work.)
I've used the Vuex helper mapState
to map the state properties to the component. Using getters would also work but mapState
is easier to write.
Please have a look at the demo below or this fiddle.
Also uncomment the code below the Vuex version in the fiddle and comment the app above to see how Axios is working with-out Vuex for a better understanding.
const URL = 'https://jsonplaceholder.typicode.com/posts';
const store = new Vuex.Store({
state: {
posts: [],
loading: true
},
actions: {
loadData({
commit
}) {
axios.get(URL).then((response) => {
// console.log(response.data, this)
commit('updatePosts', response.data)
commit('changeLoadingState', false)
})
}
},
mutations: {
updatePosts(state, posts) {
state.posts = posts
},
changeLoadingState(state, loading) {
state.loading = loading
}
}
})
new Vue({
el: '#app',
computed: Vuex.mapState(['posts', 'loading']),
store,
created() {
//console.log(this.$store)
this.$store.dispatch('loadData') // dispatch loading
}
})
/*
//example with-out vuex
new Vue({
el: '#app',
data() {
return {
loading: true,
posts: [] // add posts here so reactivity is working, also undefined would be OK
}
},
created() {
//this.loading = true --> not needed already set in data
axios.get(URL).then((response) => {
// console.log(response.data, this)
this.posts = response.data
this.loading = false
})
}
})
*/
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/3.0.1/vuex.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.17.1/axios.js"></script>
<div id="app">
<div v-if="loading">
loading...
</div>
<div v-else>
<ul>
<li v-for="post in posts">
<h1>
{{post.title}}
</h1>
<p>
{{post.body}}
</p>
</li>
</ul>
</div>
</div>
Upvotes: 30