admin管理员组

文章数量:1208153

I'm interesting in creating an API wrapper and extending from axios using es6 classes. How is this possible? Axios has a method .create() which allows you to generate a new axios object

class Api extends Axios {
  constructor(...args){
    super(..args)
    this.defaults.baseURL = ''
  }
  cancelOrder (id) {
    return this.put(`/cancel/order/${id}`)
  }
}

I know I have access to this let instance = axios.create().

Any thoughts?

Attempt 1

import axios from 'axios'
const Axios = axios.create()

class Api extends Axios {
  constructor (...args) {
    super(...args)
    this.defaults.baseURL = ''
  }
  cancelOrder (id) {
    return this.put(`/cancel/order/${id}`)
  }
}

let api = new Api()

api.cancelOrder('hi')
  .then(console.log)
  .catch(console.log)

Attempt 2

import axios from 'axios'

class Axios {
  constructor () {
    return axios.create()
  }
}

class Api extends Axios {
  constructor () {
    super()
    this.defaults.baseURL = ''
  }
  cancelOrder (id) {
    return this.put(`/cancel/order/${id}`)
  }
}

let api = new Api()

console.log(api.__proto__)

api.cancelOrder('hi')
  .then(console.log)
  .catch(console.log)

I'm interesting in creating an API wrapper and extending from axios using es6 classes. How is this possible? Axios has a method .create() which allows you to generate a new axios object

class Api extends Axios {
  constructor(...args){
    super(..args)
    this.defaults.baseURL = 'https://api.com'
  }
  cancelOrder (id) {
    return this.put(`/cancel/order/${id}`)
  }
}

I know I have access to this let instance = axios.create().

Any thoughts?

Attempt 1

import axios from 'axios'
const Axios = axios.create()

class Api extends Axios {
  constructor (...args) {
    super(...args)
    this.defaults.baseURL = 'https://api.com'
  }
  cancelOrder (id) {
    return this.put(`/cancel/order/${id}`)
  }
}

let api = new Api()

api.cancelOrder('hi')
  .then(console.log)
  .catch(console.log)

Attempt 2

import axios from 'axios'

class Axios {
  constructor () {
    return axios.create()
  }
}

class Api extends Axios {
  constructor () {
    super()
    this.defaults.baseURL = 'https://api.com'
  }
  cancelOrder (id) {
    return this.put(`/cancel/order/${id}`)
  }
}

let api = new Api()

console.log(api.__proto__)

api.cancelOrder('hi')
  .then(console.log)
  .catch(console.log)
Share Improve this question edited May 13, 2016 at 19:20 ThomasReggi asked May 13, 2016 at 19:15 ThomasReggiThomasReggi 59.3k97 gold badges257 silver badges459 bronze badges 5
  • 1 I am not sure the issue here? – Tuvia Commented May 13, 2016 at 19:18
  • 1 @Tuvia the issue is i'm trying to extend Axios and I can't :( – ThomasReggi Commented May 13, 2016 at 19:19
  • 1 You cannot extend an object in es6. You can extend a prototype however. But I am not entirely sure what you are trying to do. A class (defined by es6) is something that you will have to do new MyClass to. And that MyClass is the thing you can extend – Tuvia Commented May 13, 2016 at 19:20
  • 1 And so the class impedance mismatch begins. This will take decades to unravel. – Ben Aston Commented May 13, 2016 at 19:36
  • 1 This is highly annoying that Axios can't be extended. I want to EXTEND it and add a few generic methods which I often use, and I want to keep all the original axios methods AND have it all on the same instance of something I would call "http" instead of "axios", but unfortunately it seems this kind of extension is not possible because the library devs think they know better so they won't let us do this. Facepalm. – tkit Commented Jul 29, 2019 at 15:50
Add a comment  | 

6 Answers 6

Reset to default 7

axios currently does not export the Axios class it uses internally.

The .create() method only instantiates a new instance.

// Factory for creating new instances
axios.create = function create(defaultConfig) {
  return new Axios(defaultConfig);
};

I've created a PR that exports the Axios class.

https://github.com/reggi/axios/commit/7548f2f79d20031cd89ea7c2c83f6b3a9c2b1da4

And a GitHub issue here:

https://github.com/mzabriskie/axios/issues/320

If you look at the source code of axios they do not seem to expose the "class" for Axios, only an instance.

I do not believe that an instance object can be extended in es6.


Your second attempt seems most viable, but if you want to emulate every single axios method, you may have a lot of overhead.

import axios, { Axios } from 'axios';

class Api extends Axios {
  constructor () {
    super()
    this.defaults.baseURL = 'https://api.com'
  }
  cancelOrder (id) {
    return this.put(`/cancel/order/${id}`)
  }
}

you can install this package: npm i axios-es6-class

I also wanted to create class which would allow me to create multiple instances having predefined defaults. Here is my solution.

import axios from 'axios'

export class Axios {
    constructor() {
        return axios.create({
            baseURL: 'http://127.0.0.1:8080/',
            headers: {
                Authorization: 'AUTH TOKEN FROM INSTANCE',
                'Content-Type': 'application/json',
            },
        })
   }

}

const db = new Axios()

db.get('/your_url').then().catch()

Well, many of the answers says that there's no class "Axios" exported from the axios package but that's not true atleast for version 0.26.0. Well if you want to create the Axios instance by yourself and customize it as you wish is pretty simple. I created a example using typescript feel free to use it if you want.

import { Axios, AxiosRequestConfig } from "axios";

class AxiosService<D = any> extends Axios {
  constructor(config?: AxiosRequestConfig<D>) {
    super(config);
    this.defaults.baseURL = 'https://api.com'
    
    this.interceptors.request.use(interceptorConfig => {
      // Set up your default interceptor behavior here for requests, if you want
      }
    );
    this.interceptors.response.use(
      response => {
        return response;
      },
      error => {
        // Same thing here, set the behavior for onError responses
      }
    );
   }

   cancelOrder (id) {
    return this.put(`/cancel/order/${id}`)
   }

  }
/*
  Here you can choose between exporting the class or a instance of it
  in my case i just want to export the instance with some default config
  and use it, you may ask yourself why that's because i want to centrilize
  the configs on one axios instance instead of multiple instances.
*/
const axiosInstance = new AxiosService({
  // You may want to set this so axios automatically parse your data to a object.
  transformResponse: res => { 
    return JSON.parse(res);
  },
  transformRequest: req => {
    return JSON.stringify(req);
  },
  headers: { 
    "Access-Control-Allow-Origin": "true",
    'Content-Type': 'application/json'
 },
});

export { axiosInstance };

Disclaimer: think really well before going into this implementation because 99% of axios default configs, functions, helpers, etc will not be attached to this instance so you will have to insert them manually like we did when we instanciated a axiosService. But if all of axios stuff doesnt matter for you and you want to create a instance from scratch or even a basic instance to be used in some especific places feel free to do it. So most of times just import axios from "axios" and use axios.create.

本文标签: javascriptUsing es6 class to extend AxiosStack Overflow