vtni
vtni

Reputation: 980

Is it possible to use toast in axios.interceptors?

I am using react-toastify to show notifications. Whenever a response with a status code of 401 receives, I want to show an error with toast. However, no notification is fired. Is this even possible (with axios intereceptors)?

This is my code:

import {Toast as toast, ToastContainer} from "react-toastify";

...
axios.interceptors.response.use(function (response) {
  return response.data;
}, function (error) {
  if (error.response.status === 401) {
    toast.error("Unauthorized");
  }
  return Promise.reject(error.data);
});

const renderApp = Component => {
  ReactDOM.render(
    <Provider store={store}>
      <I18nextProvider i18n={i18n}>
          <BrowserRouter>
              <Component />
          </BrowserRouter>
          <ToastContainer {...defaultToastProps}  />
        </I18nextProvider>
    </Provider>,
    rootElement
  );
};

Upvotes: 5

Views: 8042

Answers (1)

WizardOfAuz
WizardOfAuz

Reputation: 106

You can use react-toastify with axios interceptors quite easily. I think your import is incorrect as mentioned by @Estus Flask.

Here is a full example however in this instance I'm handling HTTP 500 globally and the login error (HTTP 403) in the catch.

Add the ToastContainer to index.js.

// index.js
...
import { ToastContainer } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';

ReactDOM.render(
  <React.StrictMode>
    <ToastContainer
    position="top-center"
    autoClose={5000}
    hideProgressBar={false}
    newestOnTop={false}
    closeOnClick
    rtl={false}
    pauseOnFocusLoss
    draggable
    pauseOnHover
    />
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);
...

Then in your interceptor you can create the toast for your desired status code:

// api-interceptor.js
import axios from 'axios';
import { toast } from 'react-toastify';

const errorHandler = (error) => {
  if (error.response.status === 500) {
    toast.error(`${error.response.data.detail}`, {
      position: "top-center",
      autoClose: false,
      hideProgressBar: false,
      closeOnClick: true,
      pauseOnHover: true,
      draggable: true,
      progress: 0,
      });  
  }

  return Promise.reject({ ...error })
}

// axios instance for making requests 
const axiosInstance = axios.create();

// response interceptor for handling common errors (e.g. HTTP 500)
axiosInstance.interceptors.response.use(
  (response) => {return response},
  (error) => errorHandler(error)
  );

export default axiosInstance;

Then your component can import the axios instance and use it as per normal knowing that your common errors (e.g. HTTP 500) are handled consistently while other errors (e.g. HTTP 403) are handled by the component.

// login-button.js
import axios from '../utils/api-interceptor';
import { toast } from 'react-toastify';

...
    const response = await axios.post(`/api/users/login`, values)
      .catch(function (error) {
        if (error.response.status === 403) { 
          toast.error("Unauthorized", {
            position: "top-center",
            hideProgressBar: false,
            closeOnClick: true,
            pauseOnHover: true,
            draggable: true,
            progress: 0,
            });  
        }
        });
...

Upvotes: 4

Related Questions