Reputation: 20289
I currently have VueJS components that makes an ajax call to github like so:
(Child) component
Vue.http.get('user/repos').then((response) => {
console.log(response);
}, (response) => {
console.log(response);
});
The problem is that I first need to get an access token before I can make this ajax call. This access token is stored in the database so my main Vue component is making the ajax call to set a common header to all ajax calls:
Main Vue instance
Vue.http.headers.common['Authorization'] = `token ${this.token}`;
const app = new Vue({
el: '#app',
data: {
token: ''
},
created() {
Vue.http.get('/token').then((response) => {
this.token = response.data.token;
}, () => {
console.log('failed to retrieve the access token for the logged in user.');
})
}
});
How can I be sure that before running the ajax call from my component that the ajax call to set the 'Authorization' header has been successful?
Upvotes: 3
Views: 4792
Reputation: 9549
Adding this for anyone else who could benefit.
Get the token from the API call, add it up in a vuex state variable.
Access the same using a getter in the child component, as a computed property or you can pass it on as props or via an event bus but both the ways are not as powerful as using vuex.
watch
over the property, and perform your required action when the token is obtained.
// Add this up in the child component
computed: {
...mapGetters({
token: <name-of-the-getter> // token becomes the alias for the computed
}) // property.
},
watch: {
token () {
if(this.token) this.someAPICall()// or some other applicable condition
}
},
methods: {
...mapActions({
someAPICall: <name-of-the-action>
})
}
// ----------------------------------------------
Watch requires the value to change, I have noticed that commits made in an action cause the watch
to trigger. So if for some reason the token is lost, or expires you will naturally not be able to make the subsequent requests.
EDIT
import store from 'path/to/store'
axios.interceptors.response.use(function (response) {
// extract the token from the response object
// save the token to the store for access during subsequent
// requests.
return response;
}, function (error) {
// Do something with response error
return Promise.reject(error);
});
axios.interceptors.request.use(function (config) {
// use store getters to access token
return config;
}, function (error) {
// Do something with request error
return Promise.reject(error);
});
Upvotes: 5
Reputation: 27450
You can replace/proxyfiy Vue.http.get function by your own function that will request token first and then do your request, rough idea:
!function()
{
var vue_http_get = Vue.http.get;
var token = null;
// patching/proxying Vue.http.get function
Vue.http.get = function get() {
vue_http_get.apply(Vue.http,"path/to/get/token/").then(function(resp){
token = resp;
Vue.http.headers.common['Authorization'] = ...;
// putting back original Vue.http
Vue.http = vue_http_get;
return Vue.http.get(arguments[0]);
});
};
}();
Upvotes: 1