Using axios globally in a Vue 3 with provide/inject (composition API)

avxkim

Alexander Kim

Posted on December 3, 2021

Using axios globally in a Vue 3 with provide/inject (composition API)

In a Vue 2 we had to use Vue.prototype in order to add global properties to a Vue instance. But in a Vue 3 we got "Composition API".

So, using a composition api, recommended way to add global properties, is by using provide/inject. Because config.globalProperties considered as an escape hatch

Let's get started.

1. Create a file called http.ts (you can name it as you wish):

import axios, { AxiosInstance } from 'axios'

const apiClient: AxiosInstance = axios.create({
  baseURL: 'https://api.openbrewerydb.org',
  headers: {
    'Content-type': 'application/json',
  },
})

export default apiClient
Enter fullscreen mode Exit fullscreen mode

It's our global Axios instance with the options.

2. Create a file symbols.ts

import { InjectionKey } from 'vue'
import { AxiosInstance } from 'axios'

export const AxiosKey: InjectionKey<AxiosInstance> = Symbol('http')
Enter fullscreen mode Exit fullscreen mode

This is required to type our Provide/Inject.

3. Go to main.ts

// libs
import http from '@/http'
import { AxiosKey } from '@/symbols'

const app = createApp(App)

app.provide(AxiosKey, http)
Enter fullscreen mode Exit fullscreen mode

We're providing our Axios instance globally here, using InjectionKey - AxiosKey, so it's typed now. Otherwise you would have to provide types every time you use inject()

4. Create a function to deal with undefined values, when you use inject():

import { inject, InjectionKey } from 'vue'

export function injectStrict<T>(key: InjectionKey<T>, fallback?: T) {
  const resolved = inject(key, fallback)
  if (!resolved) {
    throw new Error(`Could not resolve ${key.description}`)
  }
  return resolved
}
Enter fullscreen mode Exit fullscreen mode

It was found in this useful blog post

5. Using our global axios instance inside a component:

<script setup lang="ts">
import { ref, onMounted } from 'vue'

// typing inject
import { injectStrict } from '@/utils/injectTyped'
import { AxiosKey } from '@/symbols'

interface Breweries {
  id: string
  name: string
}

const http = injectStrict(AxiosKey) // it's typed now
const breweries = ref<Breweries[]>([])

onMounted(async () => {
  const resp = await http.get<Breweries[]>('/breweries')
  breweries.value = resp.data
})
</script>
Enter fullscreen mode Exit fullscreen mode
💖 💪 🙅 🚩
avxkim
Alexander Kim

Posted on December 3, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related