Reputation: 424
I've been trying to make auth refresh token calls using Redux toolkit but after installing all fixes, it still is now able to read error message.
Setting up axios instance:
export const axiosInstance = axios.create({
baseURL: REACT_APP_API_URL,
});
Making API call:
export const refreshAccessAndRefreshTokens = async () => {
const response = await axiosInstance({
method: 'post',
url: '/refresh-tokens',
withCredentials: true,
});
return response;
};
Thunk function:
// GET ACCESS TOKEN USING REFRESH TOKEN
export const refreshTokens = createAsyncThunk(
'auth/refreshTokens',
async ({ rejectWithValue }) => {
try {
const response = await refreshAccessAndRefreshTokens();
return response.data;
} catch (error) {
console.log('error', error);
console.log('data', error.response.data);
console.log('message', error.response.data.message);
return rejectWithValue(error.response.data.message);
}
}
);
Extra reducers in auth slice:
extraReducers: (builder) => {
builder
.addCase(refreshTokens.pending, (state) => {
state.loading = true;
})
.addCase(refreshTokens.fulfilled, (state, action) => {
state.loading = false;
state.isAuthenticated = true;
state.user = action.payload.user;
state.roles = action.payload.roles;
})
.addCase(refreshTokens.rejected, (state, action) => {
state.loading = false;
state.success = false;
state.message = action.payload;
state.isAuthenticated = false;
state.user = null;
state.roles = [];
})
},
I'm able to see the errors in browser console, but rejectWithMessage is not working:
Console output:
Redux output:
Refresh Tokens is being called on login page through useEffect to redirect the user to where he came from in case he is already logged in.
useEffect(() => {
dispatch(refreshTokens());
dispatch(reset());
}, [dispatch]);
useEffect(() => {
if (isAuthenticated) {
if (roles.find((role) => role === process.env.REACT_APP_ROLE)) {
navigate(from, { replace: true });
} else {
dispatch(
errorFn({
success: false,
message: 'You are not authorized to access this page!',
})
);
}
}
}, [dispatch, from, isAuthenticated, navigate, roles]);
Upvotes: 1
Views: 4157
Reputation: 27
export const canLogin = createAsyncThunk("AUTH/login",
async (loginData ,{ rejectWithValue })=> {
try{
const response=await axios.post(AuthConfig.API_URL + AuthConfig.LOGIN_URI, loginData)
return response
}
catch(error){
if (!error.response || !error.message)
throw error
return rejectWithValue(getErrorMessage(error))
}
}
);
export function getErrorMessage(error) {
return (
error?.response?.data?.message ||
error?.response?.data.error ||
error?.response?.data ||
error?.message ||
error.toString()
);
}
Upvotes: -1
Reputation: 544
The first argument that is passed to the callback function you give to createAsyncThunk
is the argument that you pass when you call the action.
take a look here for more information. The second argument is the thunkAPI
which contains the rejectWithValue
. Try putting a dummy parameter as the first parameter to the callback like this -
// GET ACCESS TOKEN USING REFRESH TOKEN
export const refreshTokens = createAsyncThunk(
'auth/refreshTokens',
async (_, { rejectWithValue }) => {
try {
const response = await refreshAccessAndRefreshTokens();
return response.data;
} catch (error) {
console.log('error', error);
console.log('data', error.response.data);
console.log('message', error.response.data.message);
return rejectWithValue(error.response.data.message);
}
}
);
Upvotes: 5