Search code examples
javascriptreactjsaxiosinterceptor

Return Response When First request failed And Try In Second Request


I try to explain the problem.in App.js I have Function getUser .when call this function.in first request get 401 error . For this reason in axios.interceptors.response I receive error 401.At this time, I receive a token and repeat my request again.And it is done successfully.But not return response in Function getUser.
I have hook for authentication and send request.

import React from "react";
import axios from "axios";

const API_URL = "http://127.0.0.1:4000/api/";

function useJWT() {

  axios.interceptors.request.use(
    (request) => {
      request.headers.common["Accept"] = "application/json";
      console.log("request Send ");
      return request;
    },
    (error) => {
      return Promise.reject(error);
    }
  );
  axios.interceptors.response.use(
    (response) => {
      console.log("answer = ", response);
      return response;
    },
    (error) => {
      if (error?.response?.status) {
        switch (error.response.status) {
          case 401:
            refreshToken().then((responseTwo) => {
              return
                sendPostRequest(
                  error.response.config.url
                    .split("/")
                    .findLast((item) => true)
                    .toString(),
                  error.response.config.data
              );
            });
            break;
          case 500:
            // Actions for Error 500
            throw error;
          default:
            console.error("from hook interceptor => ", error);
            throw error;
        }
      } else {
        // Occurs for axios error.message = 'Network Error'
        throw error;
      }
    }
  );

  const refreshToken = () => {
    const token = localStorage.getItem("refresh");
    return axios
      .post(API_URL + "token", {
        token,
      })
      .then((response) => {
        if (response.data.access) {
          localStorage.setItem("access", response.data.access);
        }
        if (response.data.refresh) {
          localStorage.setItem("refresh", response.data.refresh);
        }
        return response.data;
      });
  };

  function login(email, password) {
    return axios
      .post(API_URL + "login", {
        email,
        password,
      })
      .then((response) => {
        if (response.data.access) {
          localStorage.setItem("access", response.data.access);
        }
        if (response.data.refresh) {
          localStorage.setItem("refresh", response.data.refresh);
        }
        return response.data;
      });
  }

  const sendPostRequest = (url, data) => {
    console.log(300);
    const token = localStorage.getItem("access");
    axios.defaults.headers.common["jwt"] = token;

    return axios.post(API_URL + url, {
      data,
    });
  };

  const logout = () => {
    const token = localStorage.getItem("refresh");
    return axios
      .delete(API_URL + "logout", {
        token,
      })
      .then((response) => {
        localStorage.removeItem("access");
        localStorage.removeItem("refresh");
      });
  };

  return {
    login,
    logout,
    refreshToken,
    sendPostRequest,
  };
}

export default useJWT;


In App.js ,I want to repeat the same request again if a 401 error is issued when I read the user information. The request is successfully repeated but does not return the value.
When first request fail response is return equals null . and in catch when receive 401 error i am send second request but not return response.
I send request below code .
const getUser = () => {
 console.log(12);
 return sendPostRequest("user");
  };

  useEffect(() => {
    let token = localStorage.getItem("access");
    console.log("token = ", token);
    if (token != null) {
      //Here I have done simulation for 401 error
     localStorage.setItem("access", "");
       getUser()
         .then((response) => {
           console.log("response 1= ", response);
         })
    .catch((exception) => {
      console.log("exception = ", exception.toString());
    })
    .then((response) => {
      console.log("response 2= ", response);
    });
} else {
  navigate("/login");
}
 }, []);

Best regards.

Solution

  • I find anwser for this question.
    When error 401 occurs then create new Promise
    I Wrote this code.

    case 401:
            return new Promise((resolve, reject) => {
              refreshToken().then((responseTwo) => {
                resolve(
                  sendPostRequest(
                    error.response.config.url
                      .split("/")
                      .findLast((item) => true)
                      .toString(),
                    error.response.config.data
                  )
                );
              });
            });