Show modal from axios response interceptor. React

Viewed 4656

I have a small project where I am using React without Redux or Router. Also I use axios for every request.

What I need to do is that in case any response has 401 error code I need to show some kind of modal with appropriate error message.

I created an axios instance and set the response interceptor there:

const axiosInstance = axios.create({
  baseURL: URL_PREFIX,
  headers: {
    'X-Requested-With': 'XMLHttpRequest',
  },
})

axiosInstance.interceptors.response.use(
  response => response,
  error => {
    if(error.response.status === 401) {
      // I want to show modal from here, 
      // but this is outside of my component tree
      // and I can not access my modal state to set it open.
    }
    return error
  }
)

Then I use my created axios instance for every API call.

I also tried to set the response interceptor from my root components useEffect() method. But it does not work

Is there any good way to accomplish this without using Redux or Router ?

1 Answers

You can use axios.catch() method:

axios.get('url')
  .then(response => // response.data )

  .catch((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.status);
    } 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);
    } else {
      // Something happened in setting up the request that triggered an Error
      console.log('Error', error.message);
    }
    console.log(error.config);
  });

Update:

Create an instance module:

// axiosInstance.js
import axios from "axios"

const axiosInstance = axios.create({
  baseURL: "url"
})

// You can do the same with `request interceptor`
axiosInstance.interceptors.response.use(
  response => {
    // intercept response...
    return response
  },
  error => {
    // intercept errors
    return Promise.reject(error)
  }
)
// You can create/export more then one
export { axiosInstance }

Then import it in your component:

import { axiosInstance } from "./axiosInstance"

const SomeComponent = () => {
  // You may want to use state to store the returned values ...

  useEffect(() => {
    // Call the instance
    axiosInstance.get().then(res => {
      if (res.status === 200) {
        // Everything is OK

        // Else, check if the error object is exist
      } else if (res.response) {
        // Error object: `res.response`
        // For error codes: `res.response.status`
        if(res.response.status === 401) {
          // Do your stuff
        }
      }
    })
  }, [])

  return ( ... )
}

Edit react useContext hook

Related