Search code examples
reactjsexpressreduxaxioshttp-status-code-304

Getting status code 304 on a get request with axios using react and redux


I have a get request in my Redux Async Thunk. After calling get to my node.js express server it sends a 304 status code, for some reason I can't get my data.

const userTokenAxios = axios.create({
  baseURL: '/api/shoes',
  headers: {
    Authorization: `Bearer ${localStorage.getItem('token')}`,
  },
});

userTokenAxios.interceptors.response.use((response) => {
  if (response.data.errorMessage === 'jwt expired') {
    localStorage.removeItem('token');
    localStorage.removeItem('user');
  }
});

export const getShoesAsync = createAsyncThunk(
  'shoes/getShoesAsync',
  async (payload, { rejectWithValue }) => {
    try {
      const response = await userTokenAxios.get('/');
      console.log(response);
      return response.data;
    } catch (error) {
      return rejectWithValue(error.response.data);
    }
  }
);

Its being called from my homepage:

useEffect(() => {
    dispatch(getShoesAsync());
  }, [dispatch]);

But I can't get any data as every time the page loads the server sends a 304

my backend controller:

exports.getAllShoes = async (req, res, next) => {
  try {
    let query = Shoe.find({});
    const shoes = await query.populate([
      {
        path: 'user',
        select: 'username',
      },
    ]);

    return res.status(200).json(shoes);
  } catch (err) {
    return next(err);
  }
};

app.js in my backend folder:

// ROUTES
app.use('/auth', authRouter);
app.use(
  '/api',
  expressJwt({ secret: process.env.JWT_SECRET, algorithms: ['HS256'] })
);
app.use('/api/shoes', shoeRouter);

package.json in my client folder

"proxy": "http://localhost:9000"

My network preview:

network preview


Solution

  • The problem is your interceptor. Response interceptors must return a value, a rejected promise or throw an error, otherwise the resulting promise will resolve with undefined.

    It also seems odd that you're intercepting token errors in the successful response interceptor. I would have assumed you'd use the error interceptor.

    userTokenAxios.interceptors.response.use(
      res => res, // success response interceptor
      err => {
        // usually you'd look for a 401 status ¯\_(ツ)_/¯
        if (err.response?.data?.errorMessage === "jwt expired") {
          localStorage.removeItem('token');
          localStorage.removeItem('user');
        }
    
        return Promise.reject(err);
      }
    );
    

    If you are actually responding with a 200 status for token errors, you'd need to handle it in the success interceptor

    userTokenAxios.interceptors.response.use(
      res => {
        if (res.data.errorMessage === "jwt expired") {
          localStorage.removeItem('token');
          localStorage.removeItem('user');
    
          // Make this look like an Axios error
          return Promise.reject({
            message: "jwt expired",
            response: res,
          });
        }
    
        return res;
      }
    );
    

    It also looks like you don't need the trailing forward-slash in your request so simply use

    const response = await userTokenAxios.get("");