Anoop Thiruonam
Anoop Thiruonam

Reputation: 2872

How to use axios in Vue2 project created with vue-cli3

I created a new vue project using the command vue create axe using vue-cli-3.0.016beta. Then installed axios using npm install axios --save. In the main.js file I imported axios as shown below.

import Vue from 'vue'
import App from './App.vue'

import axios from 'axios'

Vue.config.productionTip = false
Vue.use(axios)

new Vue({
    render: h => h(App)
}).$mount('#app')

There is not a bit of code change other than this. Still I get an error like the following:

Unhandled promise rejection 
TypeError
​
columnNumber: 7
​
fileName: "http://localhost:8080/app.js line 1065 > eval"
​
lineNumber: 57
​
message: "parsed is undefined"
​
stack: "isURLSameOrigin@webpack-internal:///./node_modules/axios/lib/helpers/isURLSameOrigin.js:57:7\ndispatchXhrRequest@webpack-internal:///./node_modules/axios/lib/adapters/xhr.js:109:50\nPromise@webpack-internal:///./node_modules/core-js/modules/es6.promise.js:177:7\nxhrAdapter@webpack-internal:///./node_modules/axios/lib/adapters/xhr.js:12:10\ndispatchRequest@webpack-internal:///./node_modules/axios/lib/core/dispatchRequest.js:59:10\nrun@webpack-internal:///./node_modules/core-js/modules/es6.promise.js:75:22\nnotify/<@webpack-internal:///./node_modules/core-js/modules/es6.promise.js:92:30\nflush@webpack-internal:///./node_modules/core-js/modules/_microtask.js:18:9\n"
​
__proto__: Object { stack: "", … }

I want to axios globally to use interceptors, hence calling it here in main.js. But if I use it in a view-page there is no error!

is this a bug or I'm doing it wrong? Kindly help me to fix this and use axios globally.

Thanks

Upvotes: 2

Views: 4486

Answers (2)

billychan
billychan

Reputation: 59

instead of

Vue.use(axios);

you should

Vue.prototype.$axios = axios;

then you can use it globally

login() {
    this.$axios.post('<host>/api/login', data)
        .then((res) => { // dosomething })
        .catch((err) => { // dosomething });    
}

if you want to add globally interceptors with axios, you can

// Add a request interceptor
axios.interceptors.request.use(function (config) {
    // Do something before request is sent
    return config;
}, function (error) {
    // Do something with request error
    return Promise.reject(error);
});

// Add a response interceptor
axios.interceptors.response.use(function (response) {
    // Do something with response data
    return response;
}, function (error) {
    // Do something with response error
    return Promise.reject(error);
});

// and
Vue.prototype.$axios = axios;

Upvotes: 1

Daniel
Daniel

Reputation: 35714

so the error I see is here

Vue.use(axios)

Vue.use expects a vue installable plugin.

You could have a look at vue-axios

import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios, axios)

but I would highly discourage it.

It's best to create your own ApiHandler.js file that handles all the remote stuff separately, and you can easily call from anywhere including vue components and vuex.

here is the beginning of my class

<script>
import axios from 'axios';

class ApiHandler{
  constructor(apiUrl) {
    this.axios = axios;
    this.apiUrl = apiUrl || '';  // this line allow passing a custom endpoint for testing
    this.config = {
      headers: { 'Cache-Control': 'no-cache' },  // can setup to prevent all caching
      baseURL: this.apiUrl,
    };
  }

  /**
   * @param {Object} payload
   * @param {String} payload.username
   * @param {String} payload.password
   */
  login({ username, password }) {
    return new Promise((resolve, reject) => {
      this.axios.post('/api/login', { username: username.toLowerCase(), password }, this.config)
        .then((response) => {
          if (response.code === 200 && response.body && response.body.token) {
            resolve(response.body.token);
          } else {
            reject('Bad Login');
          }
        })
        .catch((err) => {
          reject('internal error');
        });
    });
  }
}
</script>

you can then call this from anywhere by...

<script>
  import ApiHandler from '../lib/ApiHandler';
  const apiRequest = new ApiRequest();

  // and then anywhere in the script
  let payload = {
    username:'someuser',
    password:'somepassword',
  };
  apiRequest.login(payload)
    .then(()=>{
      // yay - I'm logged in
    })
    .catch(err => {
      // oh oh, display error
    })
</script>

this gives you much more flexibility and allows you to separate the remote actions and allows doing first-leg response handling separate of your component, which allows more re-usability.

Upvotes: 2

Related Questions