Default query params not getting passed in axios r

2020-03-23 06:13发布

问题:

I'm using axios.create() to pass in a baseURL and some default query params like this

axios.create({
    baseURL: 'http://somebigurlhere',
    params: {
        part: 'part',
        maxResults: 5,
        key: 'key'
   }
});

When I use

axios.get('/search', {
    params: {
        q: 'word'
    }
});

the default params do not get merged in the GET call.

What I get is http://somebigurlhere/search?q=word

instead of http://somebigurlhere/search?part=part&maxResults=5&key=key&q=asd

I tried putting the configuration in many other ways but it still doesn't work. Am i doing something wrong here ?

I tried the same in other projects and it is working there. Just created a new react app with create-react-app and this doesn't seem to work anymore.

回答1:

I solved it using 2 ways:

  1. Using default params and spreading them when using the request

    export const API_DEFAULT_PARAMS = {
      part: 'part',
      maxResults: 5,
      key: 'key'
    }
    
    export default axios.create({
      baseURL: 'http://somebigurlhere',
    });
    

    Then to use it:

    import api, { API_DEFAULT_PARAMS } from './place/where/previous/file/is';
        ....
    api.get('/search', {
       params: {
        // spread the default params
         ...API_DEFAULT_PARAMS,
        // add your own parameters here
         q: 'word',
       }
    });
    
  2. Using interceptors as a user suggested here

    const instance = axios.create({
      baseURL: 'http://somebigurlhere',
    }); 
    
    instance.interceptors.request.use(config => {
      config.params = {
       // add your default ones
       part: 'part',
       maxResults: 5,
       key: 'key',
       // spread the request's params
        ...config.params,
      };
      return config;
    });
    
    export default instance; 
    

    Then to use it

    import api from './place/where/previous/file/is';
    ...
    api.get('/search', {
     params: {
       q: 'word',
     }
    });
    

I like the interceptor approach more because it abstracts the default params to the instance file itself and you don't have to import and spread an object every time you use the instance.



回答2:

Use should return a custom object like this

const custom = axios.create({
    baseURL: 'http://somebigurlhere',
    params: {
        part: 'part',
        maxResults: 5,
        key: 'key'
   }
});

Then use the custom object to make request

custom.get('/search', {
    params: {
        q: 'word'
    }
});

Please try similar example in this codepen

Then you will see in the console, the query parameters are merged together in the request (blue line) as following image



回答3:

Just create a config object and pass it to your Axios.get request.

const config = {
    baseURL: 'www.someurl.com',
    params: {
        part: 'part',
        maxResults: 5,
        key: 'key'
    }

  }

axios.get('/waffles', config);

Example:

const config = {
    baseURL: 'https://reqres.in',
    params: {
        per_page: 3
    }
}

axios.get('/api/users?page=1', config).then(response => {console.log(response)}).catch(err => {console.log(err)});
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

If you would like to use axios.create you need to assign it to a variable as an axios instance object and then run your request against that instance.

var instance = axios.create({
    baseURL: 'https://reqres.in',
    params: {
        per_page: 5
    }
});
instance.get('/api/users?page=1').then(response => {console.log(response)}).catch(err => {console.log(err)});
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>


So for your exact example, as I said, assign axios.create to a variable then issue your .get from that.

var instance = axios.create({
        baseURL: 'http://somebigurlhere',
        params: {
            part: 'part',
            maxResults: 5,
            key: 'key'
        }
    });


instance.get('/search', {
    params: {
        q: 'word'
    }
});



Bigger Edit This edit shows how to do this in react per OPs comment in my answer. The actual sandbox demonstrating htis can be found here: https://codesandbox.io/embed/cranky-aryabhata-2773d?fontsize=14

//axios_control.js file

import axios from "axios";
export const instance = axios.create({
  baseURL: "https://reqres.in",
  params: {
    per_page: 5
  }
});


// index.js file Take note of the import from axios_control and the usage to log the return data right before the render.

import React from "react";
import ReactDOM from "react-dom";
import { instance } from "./axios_control";

import "./styles.css";

function App() {
  instance.get("/api/users").then(response => {
    console.log(response);
  });

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);