I'm doing a login view for my application and I have at tough time getting this right. I'm pretty new at this so the solution may be trival for you. I have a presenter and a login view, now I want to catch the error in the presenter and then send it over as prop to my view and handle it there. How should I go about solving this?
My first solution was to just solve everything in the presenter but that seemed wrong to do that because it doesn't follow the rules of MVP. I did this in the presenter :
try {await props.model.signIn(email, password)
}
catch (error) {
var errorMessage = error.message;
if (errorMessage.includes("password")) {
document.getElementById("error").innerHTML = "Wrong password, try again"}
This works but it doesn't follow the rules of MVP.
The solution was then to use react state hooks for error handling. What I want to do is when I catch the error in the presenter, to send it down as a prop to the view then handle the error there instead.
I began by declaring the state:
const [error,setError] = React.useState('')
then in the catch I did:
setError(error)
Then I send it to my view as a prop:
return <LoginView onUserLogIn={handleLoginACB} error = {error} />
LoginView has this in the render to show the error to the user:
<div id = "error">{errorHandling()}</div>
I then do the error handling in a function in view called errorHandling.
But then when I handle it in my view it says that the props.error is not defined. What is the proper way to send an error prop from the presenter to view, and display it?
import LoginView from "../views/loginView";
import React from "react";
function Login(props) {
const [error,setError] = React.useState('')
async function handleLoginACB() {
var email = document.getElementById('email').value
var password = document.getElementById('password').value
try {
await props.model.signIn(email, password)
} catch (error) {
console.log(error.message)
setError(error)
}
if (props.model.currentUser != null) {
window.location.hash = "#HomeScreen"
}
}
return <LoginView onUserLogIn={handleLoginACB} error = {error} />
}
export default Login;
function LoginView(props) {
return( <div className="loginBox">
<img src="logo.svg" className="image blob"/>
<form>
<input type = "email" placeholder = "Email" id="email"></input>
<div><input type = "password" placeholder = "Password" id="password"></input></div>
<div id = "error">{errorHandling}</div>
<a href="#CreateAccount">Create a new account</a>
</form>
<button onClick={props.onUserLogIn}>Log in</button>
</div>);
function errorHandling(){
console.log(props.error.message)
if (props.error.message.includes("password")) {
return "Wrong password, try again"
}
if (props.error.message.includes("email")) {
return "Wrong email, try again"
}
}
}
export default LoginView;
This does not feel
Reacty. Also, I think you are overengineering this. Unless you have to manage a complex state pipeline with things like Redux and Saga, I don't feel the need to go beyond self-contained Components for most use cases.But, I will try to make this more
Reacty while trying to maintain the MVP architecture.Login.jsxLoginView.jsxEvent Handler
Login.jsxLoginView.jsx