Supabase signup with react state email and password - reactjs

I am trying to implement the standard Supabase signup, using react-jsx, but keep getting the response:
"You must provide either an email or phone number and a password"
My code looks as follows:
const [login, setLogin] = useState('')
const [password, setPassword] = useState('')
const signUpSubmitted = () => {
supabase.auth
.signUp({ login, password })
.then((response) => {response.error ? alert(response.error.message) : setToken(response)})
.catch((err) => { alert(err)})
}
and the form:
<form id='sign-up'>
<h3>Sign Up</h3>
<label>Email:</label>
<input
type='email'
value={login}
onChange={(e) => setLogin(e.target.value)}
/>
<label>Password:</label>
<input
type='password'
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
<input onClick={signUpSubmitted} type='submit'/>
</form>
I assume the problem lies with me attempting to save the values in a state, before passing them to the database. I don't see why it should be a problem, they are both strings from what I understand, so maybe I'm way off.

According to the Supabase docs, you need to pass email instead of login.
const { data, error } = await supabase.auth.signUp({
email: 'example#email.com',
password: 'example-password',
})
I would also suggest a few other optimizations:
Move your submit handler to the <form /> in order to support submitting the form with the Enter key.
Add event.preventDefault() to your submit handler to prevent the default form browser redirection behavior.
Change your submit input to a more semantic <button />.
Link your labels and inputs together with htmlFor and id attributes for accessibility (just make sure they're unique ids).
Updated Component:
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [token, setToken] = useState();
const handleSubmit = (event) => {
event.preventDefault();
supabase.auth
.signUp({ email, password })
.then((response) => {
response.error ? alert(response.error.message) : setToken(response)
})
.catch((err) => { alert(err) });
}
return (
<form id="sign-up" onSubmit={handleSubmit}>
<h3>Sign Up</h3>
<label htmlFor="email">Email:</label>
<input
id="email"
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<label htmlFor="password">Password:</label>
<input
id="password"
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
<button type="submit">Sign Up</button>
</form>
);

Related

Fields tied to the state doesn't clear on successful form submission

I have a contact form, when the form submission is successful it should clear the form field name, email and message which is tied up to the state. The form submission is successful but form fields name, email and message doesn't clear.
For test purpose what I'm doing is passing default values to the state but this values doesn't get filled in form during initial load.
export default function Contact() {
const [name, setName] = useState('John Doe')
const [email, setEmail] = useState('me#example.com')
const [message, setMessage] = useState('Hello, this is test message.')
const onSubmit = (e) => {
e.preventDefault()
const form = {"name": name, "email": email, "message": message}
return fetch('/api/contact', {
method: 'POST',
body: JSON.stringify(form),
headers: {'Content-Type': 'application/json'}
}).then(response => {
if(response.status === 200){
setName('')
setEmail('')
setMessage('')
} else {
}
}).catch(err => err)
}
return (
<section>
<form method='post'>
<div>
<label>Name</label>
<input type="text" name="name" onChange={(e) => {setName(e.target.value)}}/>
</div>
<div>
<label>Email Address</label>
<input type="email" name="email" onChange={(e) => {setEmail(e.target.value)}}/>
</div>
<div>
<label>Message</label>
<textarea minLength={5} maxLength={2000} rows="6" name="message" onChange={(e) => {setMessage(e.target.value)}}></textarea>
</div>
<div>
<button type='submit' onClick={(e) => {onSubmit(e)}}>Send Message</button>
</div>
</form>
</section>
);
}
As User456 said, you need to add value={variable} for every <input />.
Example:
import { useState } from "react";
export default function Contact() {
const [name, setName] = useState("John Doe");
const [email, setEmail] = useState("me#example.com");
const [message, setMessage] = useState("Hello, this is test message.");
const onSubmit = (e: any) => {
e.preventDefault();
setName("");
setEmail("");
setMessage("");
};
return (
<section>
<form method="post">
<div>
<label>Name</label>
<input
type="text"
name="name"
value={name}
onChange={e => {
setName(e.target.value);
}}
/>
</div>
<div>
<label>Email Address</label>
<input
type="email"
name="email"
value={email}
onChange={e => {
setEmail(e.target.value);
}}
/>
</div>
<div>
<label>Message</label>
<textarea
minLength={5}
maxLength={2000}
name="message"
value={message}
onChange={e => {
setMessage(e.target.value);
}}></textarea>
</div>
<div>
<button
type="submit"
onClick={e => {
onSubmit(e);
}}>
Send Message
</button>
</div>
</form>
</section>
);
}

Conditional statement to show registration success message is showing the error message even when successful?

I wasn't sure how to phrase the title but basically, I am following a tutorial to create a login/registration and I am currently trying to display a message indicating whether the registration attempt was successful or not.
Here is my Register.js
import React, { useState } from 'react';
import { Form, Button } from 'react-bootstrap';
import axios from "axios";
export default function Register() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [register, setRegister] = useState(false);
const handleSubmit = (e) => {
// prevent the form from refreshing the whole page
e.preventDefault();
//set configuration
const configuration = {
method: "post",
url: "https://nodejs-mongodb-auth-app-learn.herokuapp.com/register",
data: {
email,
password,
},
};
// API call
axios(configuration)
.then((result) => {
console.log(result);
setRegister=(true);
})
.catch((error) => {
error= new Error;
})
};
return (
<>
<h2>Register</h2>
<Form onSubmit={(e)=>handleSubmit(e)}>
{/* email */}
<Form.Group controlId="formBasicEmail">
<Form.Label>Email Address</Form.Label>
<Form.Control
type="email"
name="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="Enter email"
/>
</Form.Group>
{/* password */}
<Form.Group controlId="formBasicPassword">
<Form.Label>Password</Form.Label>
<Form.Control
type="password"
name="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="Enter password"
/>
</Form.Group>
{/* submit button */}
<Button
variant="primary"
type="submit"
onClick={(e)=>handleSubmit(e)}
>
Register
</Button>
{/* display success message */}
{register ? (
<p className="text-success">You Are Registered Successfully</p>
) : (
<p className="text-danger">You Are Not Registered</p>
)}
</Form>
</>
)
};
The successful registration will log on the console, but either setRegister is not updating register to true, or my conditional statement is incorrect in some way?
It always shows "You Are Not Registered".
The correct way to ser an state using useState hook is:
e.g
const [register, setRegister] = useState(false);
setRegister(true)

my state is not getting value into it REACT

I added two handlers to my code. First, mail is entered and handleStart is started, then the user name and password are obtained from the user, and then when the button is pressed, handleFinish is activated and information assignments are made. setEmail state works but password and name states do not
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [name, setName] = useState("");
const history = useHistory();
const url = "http://localhost:3002/register";
const emailRef = useRef();
const passwordRef = useRef();
const usernameRef = useRef();
const handleStart = () => {
setEmail(emailRef.current.value);
}
const handleFinish = async (e) => {
e.preventDefault();
console.log("ref data", passwordRef.current.value,usernameRef.current.value)
//it works and shows values
setPassword(passwordRef.current.value);
setName(usernameRef.current.value);
console.log("state data", email, password, name)
//status values are empty except for email
try {
await axios.post(url, { email, name, password });
history.push("/");
} catch (err) { }
}
and my return (HTML) codes:
{!email ? (
<div className="input">
<input type="email" placeholder="email address" ref={emailRef} />
<button className="registerButton" onClick={handleStart}>
Get Started
</button>
</div>
) : (
<form className="input">
<input type="username" placeholder="username" ref={usernameRef} />
<input type="password" placeholder="password" ref={passwordRef} />
<button className="registerButton" onClick={handleFinish}>
Start
</button>
</form>
)}
It's better to use useState to store and get values and control element rather then using ref.
Here is the code using state, that may help you:
const App = () => {
const history = useHistory();
const url = "http://localhost:3002/register";
const [step, setStep] = useState(0)
const [email, setEmail] = useState("")
const [password, setPassword] = useState("")
const [username, setUsername] = useState("")
const handleStart = () => {
setStep(1)
}
const handleFinish = async (e) => {
e.preventDefault();
console.log("data: ", email, password, username)
try {
await axios.post(url, { email, name, password });
history.push("/");
} catch (err) { }
}
return (
step === 0 ? (
<div className="input">
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="email address"
/>
<button className="registerButton" onClick={handleStart}>
Get Started
</button>
</div>
) : (
<form className="input">
<input
type="username"
placeholder="username"
value={username}
onChange={(e) => setUsername(e.target.value)}
/>
<input
type="password"
placeholder="password"
value={password}
onChange={() => setPassword(e.target.value)}
/>
<button className="registerButton" onClick={handleFinish}>
Start
</button>
</form>
)
)
}
This is very well known problem, explained thousands time here,
that state changes are internally asynchronous means we wont get updated state on next line immediately, it takes time to complete execution of setPassword and setName, so next line after set state, console.log would be old values
console.log(passwordRef.current.value)
console.log(usernameRef.current.value)
this must have values, and logged on console but not password and name
this below behavior is correct, known and no issues here,
console.log("state data", email, password, name)
//status values are empty except for email
better would be, this below hack works always for me,
await axios.post(url, { email, usernameRef.current.value, passwordRef.current.value });
If you wish to do some activity based on value change for email, password, name using useEffect could be a better option. You can call API or perform any activity as an effect of those values change. Please find following code -
useEffect(() => {
await axios.post(url, { email, name, password });
history.push("/");
return () => {
// handle cancelling or other clean up
}
}, [email, password, name]);

Formsubmit.co form not working in reactapp

I added formsubmit service to my email form on my react application simple personal website. but it does not seem to be working. It does nothing. Does the extra javascript in there mess with the formsubmit service? I actually put my real email in just changed it for this post.
import React, { useState } from 'react';
import './styles.contactform.css';
function ContactForm() {
const [name, setName] = useState('');
const [email, setEmail] = useState('');
const [message, setMessage] = useState('');
const handleSubmit = (e) => {
e.preventDefault();
console.log(name, email, message)
setName('')
setEmail('')
setMessage('')
}
return (
<div className="contact-container">
<form className="contact-form" action="https://formsubmit.co/myemail#email.com" method="POST" onSubmit={handleSubmit}>
<input type="hidden" name="_next" value="https://notmicahclark.herokuapp.com/"/>
<input type="text" value={name} id="name" name="name" placeholder="Name..." onChange={(e) => setName(e.target.value)} required/>
<input type="email" value={email} id="email" name="email" placeholder="Email..." onChange={(e) => setEmail(e.target.value)} required/>
<img className="letter-img" src="contact_form_imagepng.png" alt="Mail Letter"/>
<input id="message" value={message} name="message" placeholder="Your message..." onChange={(e) => setMessage(e.target.value)}/>
<button type="submit" value="Submit">Submit</button>
</form>
</div>
);
}
export default ContactForm;
To overcome this issue, you can use the AJAX form feature provided by FormSubmit.
According to their documentation:
You can easily submit the form using AJAX without ever having your
users leave the page. — this even works cross-origin.
Please refer to their documentation about AJAX forms (sample code snippets are available): https://formsubmit.co/ajax-documentation
I've tested your code. The problem is that you are both using the form's HTML action field, and at the same time using your own method for form submission. Remove the action=... call and instead write this in your handleSubmit method.
fetch('https://formsubmit.co/ajax/myemail#email.com', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify(Object.fromEntries(new FormData(event.target))),
})
Should work like a charm. Add then and catch statements to your liking.

My react form is not submitting correctly

i have a problem with my react's form.
If I click twice on the submit button then at this moment, the form submits correctly and sends my various information to the database.
Where is the problem ?
import React, { useState } from 'react';
import axios from 'axios';
const Register = () => {
const [username, setUsername] = useState();
const [password, setPassword] = useState();
const onSubmit = (e) => {
e.preventDefault();
setUsername(document.querySelector(".usernameInput").value);
setPassword(document.querySelector(".passwordInput").value);
const user = {
username: username,
password: password
}
axios.post('http://localhost:5000/users/add', user)
.then(res => console.log(res.data));
console.log("lancement du formulaire");
}
return (
<div>
<h1>TEST Form</h1>
<form onSubmit={onSubmit}>
<div className="form-group">
<label>Username</label>
<input required type="text" className="usernameInput" />
</div>
<div className="form-group">
<label>Password</label>
<input required type="password" />
</div>
<div className="form-group">
<input type="submit" value="Create User" className="btn btn-primary" className="passwordInput" /> </div>
</form>
</div>
)
}
export default Register;
Thanks .
useState is asynchronous just like setState in class components. You can't update the state on one line and assume it's already changed on the next one. You'll likely use the unchanged state.
When you create the user object, the state is not yet updated.
You need to click twice on the submit button because:
on the first click you set the username and password states' value to the input value but as the state is not updated, you send the user objects with empty properties
on the second click (when the state is updated) you can send the user object, as the user object contains the state values
The following should work (though I would recommend not to use it):
const onSubmit = (e) => {
e.preventDefault();
const user = {
username: document.querySelector('.usernameInput').value,
password: document.querySelector('.passwordInput').value,
};
axios
.post('http://localhost:5000/users/add', user)
.then((res) => console.log(res.data));
console.log('lancement du formulaire');
};
But why do you use states username and password if you never use them? If you've already added the states to store the input values, you can update them on changes and submit them on form submit:
const Register = () => {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const onSubmit = (e) => {
e.preventDefault();
const user = {
username,
password,
};
axios
.post('http://localhost:5000/users/add', user)
.then((res) => console.log(res.data));
console.log('lancement du formulaire');
};
return (
<div>
<h1>TEST Form</h1>
<form onSubmit={onSubmit}>
<div className="form-group">
<label>Username</label>
<input
required
type="text"
className="usernameInput"
value={username}
onChange={(e) => setUsername(e.target.value)}
/>
</div>
<div className="form-group">
<label>Password</label>
<input
required
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
</div>
<div className="form-group">
<input
type="submit"
value="Create User"
className="btn btn-primary"
className="passwordInput"
/>{' '}
</div>
</form>
</div>
);
};

Resources