Dom
Dom

Reputation: 3444

Generic function to request api with Axios

I am trying to build a generic function for my endpoints, using Axios and React. Generic because I have always the same header and I do not want to repeat a lot of code for each of my components.

To do that, I built this function (sorry, a lot of comments that I will remove after of course) :

export const getRequest = ( endpoint ) => axios
.get( env._URL_SERVER_ + endpoint, { headers: getHeaders() } )
.then((res) => {
    // Success
    console.log(res);
    return {error: false, response: res.data};
}) 
.catch((error) => {
    // Error
    if (error.response) {
        /*
         * The request was made and the server responded with a
         * status code that falls out of the range of 2xx
         */
        console.log(error.response.data);
        console.log(error.response.status);
        return {error: true, status: error.response.status, data: error.response.data};
    } else if (error.request) {
        /*
         * The request was made but no response was received, `error.request`
         * is an instance of XMLHttpRequest in the browser and an instance
         * of http.ClientRequest in Node.js
         */
        console.log(error.request);
        return {error: true, data: error.request };
    } else {
        // Something happened in setting up the request and triggered an Error
        console.log('Error', error.message);
        return {error: true, data: error.message}
    }
});

Ant then in my components I do that :

getSchools = () => {
    this.setState({
        loadingSchools: true
    }, () => {
        getRequest(`/schools?name=${this.state.filterByName}&city=${this.state.filterByCity}&school_type_id=${this.state.filterBySchoolTypeId}&page=${this.state.selectedPage}`)
        .then((response) => {
            // there is an error
            if (!response.error) {
                this.setState({
                    schools: response.response.data,
                    meta: response.response.meta,
                    links: response.response.links
                })
            } else {
                this.setState({
                    error: true,
                    errorMessage: response.data, 
                })  
            } 
        })
        .then(() => {
            this.setState({loadingSchools : false});
        })
    })
}

It works fine. I tested it in several situation (all is OK - 200, not found - 404, no response). But is it a good practice ? I feel that there is a lot of codes in the parent component. Maybe I complicate my life?

Upvotes: 2

Views: 8227

Answers (2)

Shubham Khunt
Shubham Khunt

Reputation: 361

create one common file for base URL let's say api.js

// api.js file code
    export const apiUrl = axios.create({
      baseURL: 'http://localhost:5000',
    });

Register file

// register.js file code

    import { apiUrl } from './api';
    try {
      const resp = await apiUrl.post('/api/register', {
        username,
        email,
        password,
      });
      const { data, status } = resp;
      if (Object.keys(data).length && status === 200) {
        // received api data successfully
        console.log('API response', data);
      }
    } catch (err) {
      console.log(err);
    }

// For auth request
try {
  const token = localstorage.getItem('token');
  const res = await apiUrl.post(
    '/authroute',
    {
      name: fullName,
      originCountry: country,
      career: careerStatus,
    },
    {
      headers: { Authorization: `Bearer ${token}` },
    }
  );

  const { data, status } = strapiRes;

  if (Object.keys(data).length && status === 200) {
    return res.status(status).json(data);
  }
} catch (error) {
  throw new Error(error);
}

// same for all request
apiUrl.get(endpoint);
apiUrl.post(endpoint, body);
apiUrl.put(endpoint, body);
apiUrl.delete(endpoint, body);

Upvotes: 2

Hamza Sabir
Hamza Sabir

Reputation: 73

Here is how I've done it:

var URL_BACKEND = "http://localhost:5000/";
// Create Function to handle requests from the backend
    callToBackend = async (ENDPOINT, METHOD) => {
        const options = {
            url: `${URL_BACKEND}${ENDPOINT}`,
            method: METHOD,
            headers: {
              Accept: "application/json",
              "Content-Type": "application/json;charset=UTF-8",
            },
          };

        const response = await axios(options);
        return response.data;
    }
// Then you make a call with the exact endpoint and method:

        const response = await this.callToBackend('createSetupIntent', 'POST');
console.log(JSON.stringify(response));

Upvotes: 4

Related Questions