rugbert
rugbert

Reputation: 12653

Vue 2, Axios custom instance, Vuex, and Typescript

I am very new to using Typescript, but I am not having a great time with it and Vuex/Axios.

Setup: Vue CLI app, Vue 2, Vuex 3, Axios, Typescript

High level: I have a custom Axios instance where I am setting the baseURL, interceptors, timeout settings, etc. I'm importing Axios and then using axios.create() to set my configs.

I want to use this instance of Axios from any component, or the Vuex store like so this.$api.get()

Right now, I have a file for my Axios instance:

import Vue from 'vue';
import axios from 'axios';

const $api = axios.create(
  {
    baseURL: 'https://myapi.com',
    headers: {
      ...
    },
    timeout: 20000,
    timeoutErrorMessage: 'timeout',
    ...
  },
);

Vue.prototype.$api = $api;

In my Vuex store actions store/index.ts

export default new Vuex.Store({
  ...
  actions: {
    async fetchUser({ commit }): Promise<void> {
      const path = '/me';
      const user = await this.$api.get(path);

      commit('setUser', user);
    },
   }
});

Then my main.ts file:

import Vue from 'vue';
import store from './store';
import IndexPage from './pages/index.vue';

require('./plugins/api');

Vue.config.productionTip = false;

new Vue({
  store,
  render: (h) => h(IndexPage),
}).$mount('#app');

But I'll get errors like this: Property '$api' does not exist on type 'Store<{ user: User; courses: Course[]; }>'.

I've tried to use the Vue-axios npm package and access the API with Vue.$api.get()

 Property '$api' does not exist on type 'VueConstructor

Upvotes: 0

Views: 683

Answers (1)

tao
tao

Reputation: 90068

Inside any store, regardless if it's vuex or pinia, this is NOT the Vue instance.
Why? One possible reason would be that a store can be consumed by multiple Vue apps, at the same time.

In other words:

I want to use this instance of Axios from any component, or the Vuex store like...

is not possible. Unless you import it in every store and declare it on the store instance. But there's no point in attaching it to the store. You can use it directly once imported.
In more detail, this is how it's typically done:

some-file.ts

export const $api = axios.create({...})
// 👆

in any store:

import { $api } from '/path/to/some-file'
// 👆
// you can now use `$api` directly in any action, mutation, getter, etc...

Note: you should still register it on the Vue instance, so it's usable as this.$api in any component.

Upvotes: 1

Related Questions