Vue JS
# Using Vue Resource Interceptor with TypeScript and Vue JS
When you are using a Vue JS and TypeScript setup for a project, you may come across a scenario where you may want to use vue-resource
interceptors to pre and postprocess a API request.
Suppose you are creating an application which has a login flow and after login we get a auth_token
which we generally store in browser stoarge and with all other API's after login you wish to send the auth_token
in the request header. Instead of adding the token in header of every request you make, we can intercept every request at one place and add the auth_token
to the header if that token is present in our localStorage.
We may use vue-resource interceptors for this purpose.
# Installing vue-resource
You can install it using yarn or npm depending on what package manager you are using with your project as:
yarn add vue-resource
npm install vue-resource
Then in your main.ts
file import vue-resource:
import VueResource from 'vue-resource';
and finally to use it with vue add:
Vue.use(VueResource);
After this you will have access to Vue.http
in the main.ts
file and in all your vue components you will have access to this.$http
to make your requests.
# Setting up interceptors
Now the problem that we are trying to solve is that after login whenever we make an API call we want to add the auth_token
which let's say is stored in localStorage of the browser with key as auth_token
in the header of every request as X-Authorization-Token
and if the token is invalid for any request we would get back 401
status code which means token is invalid and request is unauthorized
.
Let's say if we get 401 we would clear the auth_token
from the localStorage and route them back to login. So the simple js implementation would look something like this:
Vue.http.interceptors.push((request, next) => {
if(localStorage.auth_token) {
request.headers.set('X-Authorization-Token', localStorage.auth_token);
}
next((response) => {
if(response.status == 401 ) {
localStorage.removeItem('auth_token');
router.push({ name: 'login'});
}
});
});
and we can add the above to our main.ts
file.
But when we are using TypeScript this would give us the following errors:
Property 'http' does not exist on type 'VueConstructor<Vue>'.
Parameter 'request' implicitly has an 'any' type.
Parameter 'next' implicitly has an 'any' type.
Parameter 'response' implicitly has an 'any' type.
Among these we can resolve the implicitly has an 'any' type.
error by providing a type to the request
, response
and next
because in TypeScript we have to provide a type for everything we are using and defining.
So we can simply give them a type any
to make the error go away:
Vue.http.interceptors.push((request: any, next: any) => {
if(localStorage.auth_token) {
request.headers.set('X-Authorization-Token', localStorage.auth_token);
}
next((response: any) => {
if(response.status == 401 ) {
localStorage.removeItem('auth_token');
router.push({ name: 'login'});
}
});
});
Now the error Property 'http' does not exist on type 'VueConstructor<Vue>'.
is because there is no TypeScript definition of the http
property on the Vue
object. So to resolve this we have to provide a definition of http
.
For this we will use Augmenting Types for Use with Plugins and define a simple definition of http
by creating a .d.ts
file ( The "d.ts" file is used to provide typescript type information about an API that's written in JavaScript ).
Let's create a file named http.d.ts
in the directory where our main.ts
file is present and in that file we add the following definition:
import Vue from 'vue'
declare module 'vue/types/vue' {
interface VueConstructor {
http: any
}
}
Now you will see that all the errors are resolved and we can use our vue interceptors with our TypeScript project because we augmented the type of http as any on the VueConstructor.
Learn More
- Using Vue Resource Interceptor with TypeScript and Vue JS