I try to use the vue-resource for an ajax request in an action.
// actions.js
export function loadData(state) {
Vue.$http.get('api/songs').then((value) => {
console.log('load data');
// here come maaaany logic
});
}
But i can't get it to work. this.$http or import Vue does not work.
Or is this way totally wrong? My goal is to load all data by start of my app:
// app.js <- main entry
// importing files...
new Vue({
el: '#app',
store,
components: { /* ... */ },
ready: function() {
loadData(store);
}
});
The reason why i have a lot of logic in this action is, that i will refire this action multiple times (it resets many things and fires this again).
Why close? I have same issue now. Not sure best place to handle that kind of scenario?
Hi @jonagoldman
It's question I'm having now. I can't find the example for that until now.
my case is I want to update mutation state (vuex store) which is { authenticated : true/false } in every request. Because I want to check for whether authenticated user exists or not from components .
So I have to used with beforeEach from vue-router in main.js. the thing is I can't access mutation store from main.js. And I want to know where is the most appropriate place to put vue-resource logic. eg. in store/actions.js (or) store.js (or) keep like that?
// main.js
var Vue = require('vue');
var VueRouter = require('vue-router');
var VueResource = require('vue-resource');
var Vuex = require('vuex');
Vue.use(VueRouter);
Vue.use(VueResource);
Vue.config.debug = false;
Vue.config.silent = true;
Vue.http.headers.common['X-CSRF-TOKEN'] = $('meta[name="token"]').attr('value');
var router = new VueRouter;
import Home from './frontend/home.vue';
import { checkAuth } from './vuex/actions'
var App = Vue.extend({})
var router = new VueRouter({
hashbang: false
})
router.beforeEach(function(transition) {
this.http.get('/auth/status').then(function(data) {
checkAuth(); // want to update the auth status from here to vuex store which I can't now
transition.next()
}).catch(function (data, status, request) {
// handle error.
});
}.bind(Vue))
// App routes.
router.map({
'/' : {
component: Home
},
'*': {
component: require('./components/not-found.vue')
}
})
router.start(App, '#app')
@webcrazy I don't exactly understand the problem, but a few things come to mind:
1) You don't need to update the state in every request. Just check the state to see if the user is authenticated. This can be done inside components. You can also share getters across multiple components if needed.
2) You can import the store anywhere you need it using a regular import store from './store'.
3) If you need to check something in every mutation, you can use a Middleware.
4) If you need to do something in every request, you should use Interceptors.
5) I recommend abstracting requests to an api service. Meaning take all of your this.http.get('/xxx') to different files. And the doing XXXService.get()
6) Take a look at the examples and use them as a guide.
I know I'm not being too specific, but I hope it helps.
@jonagoldman
Thanks a lot for your info. I'll try them.
@jonagoldman any example for this point?
5) I recommend abstracting requests to an api service. Meaning take all of your this.http.get('/xxx') to different files. And the doing XXXService.get()
Thanks
Auth Service (services/auth.js)
import Vue from 'vue'
export default {
authenticate(request) {
return Vue.http.post('auth/authenticate', request)
.then((response) => Promise.resolve(response.data))
.catch((error) => Promise.reject(error));
},
// other methods
}
Vuex Auth actions (vuex/actions/auth.js)
import { AUTHENTICATE, AUTHENTICATE_FAILURE } from '../mutation-types'
import authService from '../../services/auth'
export const authenticate = (store, request) => {
return authService.authenticate(request)
.then((response) => store.dispatch(AUTHENTICATE, response))
.catch((error) => store.dispatch(AUTHENTICATE_FAILURE, error));
}
// other actions
Vuex Auth module (vuex/modules/auth.js)
import { AUTHENTICATE, AUTHENTICATE_FAILURE } from '../mutation-types'
import Vue from 'vue'
// initial State
const state = {
token: null,
failure: null
}
// mutations
const mutations = {
[AUTHENTICATE] (state, response) {
state.token = response.token;
},
[AUTHENTICATE_FAILURE] (state, error) {
state.failure = error;
},
// other mutations
}
export default {
state,
mutations
}
Vuex mutation types (vuex/mutation-types.js)
export const AUTHENTICATE = 'AUTHENTICATE'
export const AUTHENTICATE_FAILURE = 'AUTHENTICATE_FAILURE'
// other mutation types
Notes:
1) I'm using Promise.resolve and Promise.reject in order to chain promises, but this is not needed in all cases. (see more here)
2) You don't need to return a promise from the authenticate() action (in 'vuex/actions/auth.js'). I'm returning a promise so I can pass it to the router state, so it can wait before entering the route.
@jonagoldman Thanks a lot for your example and detail explanation :+1:
This deserves to be in examples
I agree, these should be in the examples... I just spent an hour trying to find the best way of integrating vue-resource. Thanks for the example @jonagoldman
fyi
the solution doesn't work if there's an alias in _webpack.config.js_
resolve: {
alias: {
vue: 'vue/dist/vue.js'
}
}
I used a quick&dirty way to solve this:
import Vue from 'vue'
const Http = new Vue
Http.get('').then() ...
mark the idea of service really helpful.
@buzdykg fails without the alias too but the trick works. Thanks.
The error in my case is '_vue2.default' is undefined in '_vue2.default.$http...'
Any idea why it fails?
@jonagoldman
you example is very good! but in components how get vue-resource Promise, i hope some page action write in to, but always get in then(), I hope use catch() in the components.
I am using vue like one day, so I do not understand half of things written there.
I imported vue and vuex to my wordpress project and got $http undefined. As I understand from posts, ajax client is not part of vue nor vuex and that vue-resorce is outdated. So I just changed 'this.$http.get()' for 'axios.get()'
This helped - https://vuejsexamples.net/vuejs-ajax/
Most helpful comment
Auth Service (services/auth.js)
Vuex Auth actions (vuex/actions/auth.js)
Vuex Auth module (vuex/modules/auth.js)
Vuex mutation types (vuex/mutation-types.js)
Notes:
1) I'm using
Promise.resolveandPromise.rejectin order to chain promises, but this is not needed in all cases. (see more here)2) You don't need to return a promise from the
authenticate()action (in 'vuex/actions/auth.js'). I'm returning a promise so I can pass it to the router state, so it can wait before entering the route.