I want to access the status
sent from my Express server in my React component. I am using redux to dispatch a login fetch request and want to conditionally render different childrens based on the status code received (eg. 'Incorrect Password' if status code 401)
loginmodal.js
const handleLogin = async (event) => {
event.preventDefault();
let result = await dispatch(login({ email, password }))
console.log(result) //payload is undefined if incorrect password.
}
userAuthSlice.js (Redux)
export const login = createAsyncThunk(
'userAuth/login',
async (payload, thunkAPI) => {
const { email, password } = payload
const result = await fetch(
loginPath, {
mode: 'cors',
credentials: 'include',
method: 'post',
body: JSON.stringify({ email, password }),
headers: {
'Content-Type': 'application/json'
},
}
)
console.log(result) // Response {type: 'cors', url: 'http://localhost:5000/login', redirected: false, status: 401, ok:
const response = await result.json()
console.log(response)
return response
}
)
const userAuthSlice = createSlice({
extraReducers: {
[login.pending]: (state) => {
state.isLoading = true
},
[login.fulfilled]: (state, action) => {
state.isLoading = false
state.isAuth = true
},
[login.rejected]: (state) => {
state.isLoading = false
},
}
server.js
app.post('/login', (req, res) => {
const email = req.body.email;
const plainTextPassword = req.body.password;
User.find({ email: email }).limit(1).exec(function (err, existingUser) {
if (existingUser.length === 0) {
res.sendStatus(401)
} else {
bcrypt.compare(plainTextPassword, existingUser[0].password, function (err, response) {
if (response === true) {
req.session.user = existingUser[0]._id
res.json(req.session)
} else {
res.sendStatus(401)
}
})
}
}
)
})
In my loginModal
, i console.log the payload
from dispatch. My payload is undefined if my promise is rejected from incorrect password. My payload includes the status code if its fulfilled eg correct password. How can i get the status code / payload, even if the promise is rejected? Or is there another approach to this problem?
CodePudding user response:
You need to check the Response.ok and / or Response.status properties to determine if your request was successful.
If they are not, I would recommend returning a rejected value. The rejected object can have the properties you need like status
const res = await fetch(...);
if (!res.ok) {
// thunkApi.rejectWithValue
return rejectWithValue({
status: res.status,
message: await res.text(),
});
}
return res.json();
Then you can check for rejected promises and refer to the status
in your consuming code
const handleLogin = async (event) => {
event.preventDefault();
try {
// needs the `.unwrap()` function call
const result = await dispatch(login({ email, password })).unwrap();
console.log(result);
} catch (err) {
console.warn(err);
switch (err.status) {
case 401:
// do something for 401
break;
default:
// default error handling
}
}
}