I am developing a react native application and I am using Laravel API to implement the Login functionality.
I have successfully created the functionality, now i am in the part of showing error messages to users if for instance the email field is empty and they click the login button.
This is being done by the Laravel Backend, and i am just accessing the error list that i am recieving from the API response and sending it as a value in the AuthContext that i created.
But when i add the code for the error messages it stays persistent even if the array is empty.
How do i only let the error be shown if it is present?
Here is my code:
AuthContext:
const [loginErrorList, setLoginErrorList] = useState([])
const [loginError, setLoginError] = useState(null)
const login = (email,password) => {
axios.get("/sanctum/csrf-cookie").then((response) => {
setIsLoading(true)
axios.post("/api/login", {
email,
password
}).then((res) => {
if (res.data.status === 200) {
console.log(res.data)
setIsLoading(false)
} else if (res.data.status === 401) {
setLoginError(res.data.message)
setIsLoading(false)
} else {
setLoginErrorList(res.data.validation_errors);
setIsLoading(false)
}
}).catch(e => {
console.log(e);
setIsLoading(false)
});;
});
}
return (
<AuthContext.Provider value={{
isLoading,
loginErrorList,
loginError,
login
}}>
{children}
</AuthContext.Provider>
)
LoginScreen.js:
const {isLoading, loginErrorList, loginError, login} = useContext(AuthContext);
return (
<TextInput
style={styles.input}
value={email}
placeholder="Enter email"
onChangeText={text => setEmail(text)}
/>
{loginErrorList == [] ? "" : <Text style={{color:"red"}}>{loginErrorList.email}</Text> }// this doesn't seem to work, and if the error list is empty it just leaves a white space below the input field.
)
Laravel AuthController:
public function login(Request $request){
$validator = Validator::make($request->all(),[
'email' => 'required|max:191',
'password' => 'required',
]);
if($validator->fails()){
return response()->json([
'validation_errors' => $validator->messages(),
]);
}else{
$user = User::where('email', $request->email)->first();
if(!$user || !Hash::check($request->password, $user->password)){
return response()->json([
'status' => 401,
'message' => "Incorret Email or Password",
]);
}else{
$token = $user->createToken($user->email . '_token',[''])->plainTextToken;
return response()->json([
'status' => 200,
'username' => $user->name,
'token' => $token,
'message' => 'Logged in Successfully',
]);
}
}
}
CodePudding user response:
Your error is never being assigned to the context because the assignment occurs in your .then()
block. .then()
will only execute on successful API calls.
Replace the contents of your current .catch()
with something like:
function (error) {
if (error.response) {
// The request was made and the server responded with a status code
// that falls out of the range of 2xx
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.headers);
} else if (error.request) {
// The request was made but no response was received
// `error.request` is an instance of XMLHttpRequest in the browser and an instance of
// http.ClientRequest in node.js
console.log(error.request);
} else {
// Something happened in setting up the request that triggered an Error
console.log('Error', error.message);
}
console.log(error.config);
}
Then move the setLoginError()
into your .catch()
block function and pass it the error you are now catching.
CodePudding user response:
loginErrorList == []
will never be true (try running [] == []
in the browser console). Instead of initializing loginErrorList as []
in AuthContext, initialize it as null
and check if it is set before displaying the errors.
AuthContext.js:
const [loginErrorList, setLoginErrorList] = useState(null)
...
LoginScreen.js:
...
{loginErrorList && (
<Text style={{color:"red"}}>{loginErrorList.email}</Text>
)}