Using Vue 2 with a personalized Axios setup, integrating Vuex, and incorporating Typescript for a robust

I'm still getting the hang of Typescript, but I'm facing some challenges with it when using Vuex/Axios.

Current setup includes: Vue CLI app, Vue 2, Vuex 3, Axios, Typescript

At a high level, I have a custom Axios instance where I configure the baseURL, interceptors, timeout settings, etc. I import Axios and then use axios.create() to customize my settings.

My goal is to access this Axios instance from any component or the Vuex store using something like this.$api.get()

Currently, I have a file dedicated to 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 in 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');

However, I keep encountering errors like:

Property '$api' does not exist on type 'Store<{ user: User; courses: Course[]; }>'.

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

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

Answer №1

It is important to note that within any store, whether it be using vuex or pinia, the context of this does not refer to the Vue instance. This can be attributed to the fact that a store may be accessed by multiple Vue applications simultaneously.

To elaborate further:

Trying to utilize the Axios instance from any component, or the Vuex store, like...

is not feasible. Unless it is imported into each store and defined within the store instance. Nonetheless, it is unnecessary to attach it to the store as it can be directly accessed once imported.

Here is a common approach to achieving this:

some-file.ts

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

in any store:

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

Note: It is still advisable to register it on the Vue instance for accessibility as this.$api in any component.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Issue with Angular DevExtreme error popup

Currently, I am working on a project using Angular and DevExtreme. Whenever an error occurs, the error message seems to be hidden behind the popup form. Can anyone advise me on how to bring it to the front? Any help would be greatly appreciated. https://i ...

Compiling ES6 code into modules with the help of Webpack

Struggling to compile ES6 code into a file using Webpack? Wondering why the resulting code is not usable as it should be? Important Note: This code is intended to be a plugin for VueJS To begin, I have a basic file that exports a single function like t ...

Is there a way to incorporate a loading feature into the Vuetify datepicker?

Check out this demo: https://codepen.io/positivethinking639/pen/wvvoMpK?editors=1010 This is my HTML code: <v-dialog ref="dialog" v-model="modal" :return-value.sync="date" persistent width="290px" :loading="loading" > <template v-s ...

Retrieve identification details from a button within an ion-item located in an ion-list

<ion-list> <ion-item-group *ngFor="let group of groupedContacts"> <ion-item-divider color="light">{{group.letter}}</ion-item-divider> <ion-item *ngFor="let contact of group.contacts" class="contactlist" style="cl ...

The select event in Vuetify's v-select component does not fire when clicking on an option with a custom

Currently, I am utilizing the beta version of Vuetify (v3.0.0-beta.6) due to the necessity of using Vue 3 which is not compatible with Vuetify 2.x. My objective is to create an i18n selector featuring country flag icons. For managing i18n functionalities ...

Preventing duplicate namespace declarations in TypeScript

Let's say I have a variety of objects with the following data structure: { namespace: 'first'|'second'|'third' } Now, I need to include another object with the same data structure, but its namespace cannot be assigned ...

Exploring the functionality of useRoute within a composable in Vue

I am working on a file store/service.js and I am trying to incorporate a router. This is what I have attempted so far: import { useRoute } from 'vue-router'; const router = useRoute(); function exceptionHandler(error) { if (error.response.sta ...

Attributes not defined in Vue template

I created a component that functions as a basic generalized dialog. It has its own unique attributes that determine the icon data to display when receiving specific information from its parent component. However, I am encountering an issue where sometimes, ...

When utilizing RxJS, the process of filtering Observable data may not function as expected if the filtering is carried out within a separate function rather than directly within the subscribe

While attempting to filter data from an external source using the RxJS filter on Observables, I encountered an issue where all records were returned instead of just the ones meeting the filtering criteria. This problem occurred when the code was within a l ...

TypeError: describe is not a function in the Mocha testing framework

Encountering an issue with mocha-typescript throwing an error indicating that describe is not defined. TypeError: mocha_typescript_1.describe is not a function at DatabaseTest.WrongPath (test/database_test.ts:21:9) at Context.<anonymous> ...

I am encountering an issue with the Node library puppeteer when trying to integrate it with vue.js

While following a YouTube tutorial on utilizing puppeteer in JavaScript, I encountered an issue where the page would not render even if I required the library. The problem seemed to be located right below where I imported my Vue components: <script> ...

An error is thrown when trying to retrieve Objects: Uncaught TypeError - Object function ParsePromise()

By obtaining a Document object with its id, the following code proceeds to locate corresponding sections based on the object. The document identifies a Parse object and document.toJSON converts this into a Javascript object. Furthermore, sections represent ...

Is it possible for me to define TypeScript interfaces to be used in vanilla JavaScript projects within VSCode?

While using the MS VisualCode editor, I am attempting to implement type checking in my Javascript code. I want to maintain the flexibility of Javascript while also benefiting from type checking interfaces and data structures. Based on the vscode documenta ...

Issue with Angular 5 EventEmitter causing child to parent component emission to result in undefined output

I've been trying to pass a string from a child component to its parent component. Child Component: //imports... @Component({ selector: 'child', templateUrl: './child.component.html', styleUrls: ['./child.c ...

The configuration of the property has not been declared (Error: <spyOnProperty>)

Imagine having a MenuComponent @Component({ selector: 'cg-menu', templateUrl: './menu.component.html', styleUrls: [ './menu.component.scss' ] }) export class MenuComponent implements OnInit { menu: MenuItem[]; isLog ...

What is the best way to verify the presence of a value in an SQL column?

I need to check if a value exists in a column. If the value already exists, I do not want to insert it into the table. However, if it does not exist, then I want to add new data. Unfortunately, my attempted solution hasn't been successful. You can fi ...

Angular 2 forms, popping the chosen item in the `<select>` element

Check out the FormBuilder: let valuesArray = fb.array([ fb.group({ name: 'one' }), fb.group({ name: 'two' }), fb.group({ name: 'three' }), fb.group({ name: 'four' }) ]); this.for ...

Configurations for developing Nuxt.js single-page applications in the development server

I previously set up the devserver in vue-config.js as shown below: devServer: { proxy: { "/api/*": { target: "http://localhost:3001", secure: false } } } However, this configuration is not working in nuxt-SPA. My frontend continue ...

Tips for utilizing the keyword 'this' within a Promise

Seeking assistance with resolving an issue involving an undefined error when attempting to make an http request within a Promise function. The error occurs due to this.http.post being undefined, indicating that there is an issue with accessing this properl ...

Is there a way to refresh a MongoDB database automatically without relying on requests?

Is there a way to automatically refresh the MongoDB database without relying on user requests in order to ensure maintainable database requests and API calls that do not exceed any limits? My tech stack includes Node, Express, Vue, and Mongo. What concept ...