Not able to submit the data to firebase from contact form - javascript

import React, { useState } from 'react'
import styled from 'styled-components'
import Title from '../Components/Title'
import { InnerLayout, MainLayout } from '../Styles/Layout'
import Button from '../Components/Button'
import { db } from '../firebase';
function Contact() {
const [name, setName] = useState("");
const [email, setEmail] = useState("");
const [message, setMessage] = useState("");
const [subject, setSubject] = useState("");
const handleSubmit = (e) => {
e.preventDefault();
db.collection('mail').add({
name: name,
email: email,
subject: subject,
message: message,
})
.then(() => {
alert("Thank you for contacting. Your message has been sent successfully.");
})
.catch((err) => {
alert(err.message);
});
setName('')
setEmail('')
setSubject('')
setMessage('')
};
return (
<MainLayout>
<Title title={'Contact'} span={'Contact'} />
<ContactMain>
<InnerLayout className='contact-section'>
<div className="left-content">
<div className="contact-title">
<h4>Get In Touch</h4>
</div>
<form className="form" onSubmit={handleSubmit}>
<div className="form-field">
<label htmlFor="name">Enter Your Name</label>
<input type="text" id="name" value={name} onChange={(e) => setName(e.target.value)} />
</div>
<div className="form-field">
<label htmlFor="email">Enter Your Email</label>
<input type="email" id="email" value={email} onChange={(e) => setEmail(e.target.value)} />
</div>
<div className="form-field">
<label htmlFor="subject">Enter Your Subject</label>
<input type="text" id="subject" value={subject} onChange={(e) => setSubject(e.target.value)} />
</div>
<div className="form-field">
<label htmlFor="text-area">Enter Your Message</label>
<textarea name="textarea" id="textarea" cols="30" rows="10" value={message} onChange={(e) => setMessage(e.target.value)}></textarea>
</div>
<div className="form-field f-button">
<Button title="Send Email" />
</div>
</form>
</div>
</InnerLayout>
</ContactMain>
</MainLayout>
)
}
I don't know why but I am not able to send the details to my firebase database. I am not able to find the issue in this code. I have copied the firebase database key and all in the firebase.js and then imported it in this contact.js and I then made the necessary changes in this. Still, I am not able to figure out the issue.

I would reset the form once the promise returned by add() is resolved.
const handleSubmit = (e) => {
e.preventDefault();
db.collection('mail').add({
name: name,
email: email,
subject: subject,
message: message,
}).then(() => {
// Reset those states here
setName('')
setEmail('')
setSubject('')
setMessage('')
alert("Thank you for contacting. Your message has been sent successfully.");
}).catch((err) => {
alert(err.message);
});
};
I guess your states are being reset to "" before the document is added as those setState methods would have ran before the doc was added.

Potentially because your button html within its the button component type is not set to 'submit' - I had the same issue I think which ended up being super simple.

Related

FirebaseError: Firebase: Error (auth/invalid-email)

I am making a react project and when I am trying to sign up through email and password using firebase authentication then this 👇your text error is showing
This is the error I am getting
This is the whole code:
import React,{useState} from 'react';
import { Link, useNavigate } from 'react-router-dom';
import Layout from '../components/layout/Layout';
import {BsFillEyeFill} from "react-icons/bs";
import { getAuth, createUserWithEmailAndPassword , updateProfile} from "firebase/auth";
import {db} from "../firebase.config"
const SignUp = () => {
// to hide password
const [showPassword, setShowPassword] = useState(false);
const [formData, setFormData] = useState({
email:"",
name: "",
password: "",
})
const {name, email, password} = formData;
const navigate = useNavigate();
const onChange = (e) => {
setFormData((prevState) => ({
...prevState,
[e.target.id]: e.target.value,
}));
};
This is my signUp function
const onSubmitHandler= async (e) =>{
e.preventDefault();
try{
const auth= getAuth()
const userCredential = await createUserWithEmailAndPassword(auth,email,password);
const user = userCredential.user
updateProfile(auth.currentUser,{displayName: name})
navigate("/")
alert("Signup Success")
}catch(error){
console.log(error);
}
}
return (
<Layout>
<div className="d-flex align-items-center justify-content-center w-100 mt-5 mb-5">
<form className='bg-light p-4 rounded-3 border border-dark border-3' onSubmit={onSubmitHandler}>
<h4 className='bg-dark p-2 mt-2 text-light rounded-2 text-center'>Sign Up</h4>
<div className="mb-3">
<label htmlFor="exampleInputEmail1" className="form-label">Enter Name</label>
<input
type="text"
defaultValue={name}
id="name"
onChange={onChange}
className="form-control"
aria-describedby="nameHelp"
/>
</div>
<div className="mb-3">
<label htmlFor="exampleInputEmail1" className="form-label">Email address</label>
<input
type="email"
defaultValue={email}
onChange={onchange}
className="form-control"
id="email"
aria-describedby="emailHelp"
/>
<div id="emailHelp" className="form-text">We'll never share your email with anyone else.</div>
</div>
<div className="mb-3">
<label htmlFor="exampleInputPassword1" className="form-label">Password</label>
<input
type={showPassword? "text" : "password"}
defaultValue={password}
onChange={onchange}
className="form-control"
id="password"
/>
<span >Show Password <BsFillEyeFill
className='text-primary ms-2'
style={{cursor: "pointer"}}
onClick={()=> setShowPassword((prevState)=> !prevState)}
/></span>
</div>
<button
type="submit"
className="btn btn-primary">Sign Up</button>
<div>
<h6>Login with Google</h6>
<span>Already User?</span> <Link to="/signin">Login</Link>
</div>
</form>
</div>
</Layout>
)
}
export default SignUp
After going through firebase documentation I have tried various emails but still it is showing the same error.
This is the email I had been using for signUp.
and I tried different emails as well like: piyush#gmail.com, and my personal email too but still it is showing the same error
This is the error message for your error
auth/invalid-email:
The provided value for the email user property is invalid. It must be a string email address.
Check to make sure your onSubmitHandler is within scope of your formData state, because your email and password might be undefined.
Your code has 2 issues,
1: Check the spelling of onChange on email and password field.
2: Change defaultValue to value
Below is the working code:
import React, { useState } from 'react';
import { Link, useNavigate } from 'react-router-dom';
import { BsFillEyeFill } from 'react-icons/bs';
import {
getAuth,
createUserWithEmailAndPassword,
updateProfile,
} from 'firebase/auth';
const Signup = () => {
const [showPassword, setShowPassword] = useState(false);
const [formData, setFormData] = useState({
email: '',
name: '',
password: '',
});
const { name, email, password } = formData;
const navigate = useNavigate();
const onChange = (e: any) => {
setFormData((prevState) => ({
...prevState,
[e.target.id]: e.target.value,
}));
};
const onSubmitHandler = async (e) => {
e.preventDefault();
console.log('email is ', email, password);
try {
const auth = getAuth();
const userCredential = await createUserWithEmailAndPassword(
auth,
email,
password,
);
const user = userCredential.user;
alert('Signup Success');
} catch (error) {
console.log(error);
}
};
return (
<div className="d-flex align-items-center justify-content-center w-100 mt-5 mb-5">
<form
className="bg-light p-4 rounded-3 border border-dark border-3"
onSubmit={onSubmitHandler}
>
<h4 className="bg-dark p-2 mt-2 text-light rounded-2 text-center">
Sign Up
</h4>
<div className="mb-3">
<label htmlFor="exampleInputEmail1" className="form-label">
Enter Name
</label>
<input
type="text"
value={name}
id="name"
onChange={onChange}
className="form-control"
aria-describedby="nameHelp"
/>
</div>
<div className="mb-3">
<label htmlFor="exampleInputEmail1" className="form-label">
Email address
</label>
<input
type="email"
value={email}
onChange={onChange}
className="form-control"
id="email"
aria-describedby="emailHelp"
/>
<div id="emailHelp" className="form-text">
We'll never share your email with anyone else.
</div>
</div>
<div className="mb-3">
<label htmlFor="exampleInputPassword1" className="form-label">
Password
</label>
<input
type={showPassword ? 'text' : 'password'}
value={password}
onChange={onChange}
className="form-control"
id="password"
/>
<span>
Show Password{' '}
<BsFillEyeFill
className="text-primary ms-2"
style={{ cursor: 'pointer' }}
onClick={() => setShowPassword((prevState) => !prevState)}
/>
</span>
</div>
<button type="submit" className="btn btn-primary">
Sign Up
</button>
<div>
<h6>Login with Google</h6>
<span>Already User?</span> <Link to="/signin">Login</Link>
</div>
</form>
</div>
);
};
export default Signup;

How can I persist updated form data after submit?

So I have some formdata in my react app that I want to persist after I make a put request to the mongodb. Problem is that the change is not visible on page refresh. It is only after I log out and log in again that I can see the updated value in the form.
For example let's say that I want to change my first name from John to Eric. The change will update but not in the form. In the form the value will still be John until I log out and in again.
It feels almost like it has to do with the jwt token but I don't know. Any ideas what the problem can be?
export const Edit = () => {
const navigate = useNavigate();
const user = Cookies.get("access_token");
const [id, setId] = useState(null)
const [firstName, setFirstName] = useState("")
const [lastName, setLastName] = useState("")
const [city, setCity] = useState("")
const [email, setEmail] = useState("")
const checkUser = async () => {
try {
const res = await axios
.get(`${process.env.REACT_APP_API_URL}user/protected`, {
withCredentials: true,
headers: {
Authorization: `Bearer ${user}`,
},
})
console.log(res.data.user);
setId(res.data.user.id)
setFirstName(res.data.user.firstName)
setLastName(res.data.user.lastName)
setCity(res.data.user.city)
setEmail(res.data.user.email)
} catch (error) {
console.warn(error)
}
}
useEffect(() => {
if (!user) {
navigate('/')
} else {
checkUser();
}
}, []);
const updateUser = async () => {
try {
const userData = {
firstName: firstName,
lastName: lastName,
city: city,
email: email
}
const API_URL = `${process.env.REACT_APP_API_URL}user/`;
const userId = id;
const res = await axios.put(API_URL + "/" + userId + "/edit", userData)
setFirstName(res.data.firstName)
setLastName(res.data.lastName)
setCity(res.data.city)
setEmail(res.data.email)
// works and is updated in the database
} catch (error) {
console.warn(error)
}
}
return (
<>
<section className="m-5">
<h1 className="mb-5 text-center">Settings</h1>
<form className="row g-3">
<div className="col-md-6">
<label htmlFor="firstName" className="form-label">
First name
</label>
<p>{formErrors.firstName}</p>
<input
type="text"
className="form-control"
id="firstName"
name="firstName"
value={firstName}
onChange={(e) => setFirstName(e.target.value)}
/>
</div>
<div className="col-md-6">
<label htmlFor="lastName" className="form-label">
Last name
</label>
<p>{formErrors.lastName}</p>
<input
type="text"
className="form-control"
id="lastName"
name="lastName"
value={lastName}
onChange={(e) => setLastName(e.target.value)}
/>
</div>
<div className="col-md-6">
<label htmlFor="city" className="form-label">
City
</label>
<p>{formErrors.city}</p>
<input
type="text"
className="form-control"
id="city"
name="city"
value={city}
onChange={(e) => setCity(e.target.value)}
/>
</div>
<div className="col-md-6">
<label htmlFor="email" className="form-label">
Email
</label>
<p>{formErrors.email}</p>
<input
type="email"
className="form-control"
id="email"
name="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
</div>
<div className="col-12 pt-4 text-center">
<button
type="submit"
className="btn btn-primary btn-lg"
onClick={updateUser}
>
Update
</button>
</div>
<div className="col-12 pt-1 text-center">
<button
type="submit"
className="btn btn btn-lg"
>
<a href="edit/password" className="text-decoration-none">
Change Password
</a>
</button>
</div>
</form>
</section>
</>
);
};
Add user as a dependency to the useEffect's dependency array:
useEffect(() => {
if (!user) {
navigate('/')
} else {
checkUser();
}
}, [user]);

How can I submit the form?

I am currently making a blog website with "reactjs".In this component, I am creating new blogs by putting values of author, title, and body. I cant submit the form by hitting 'Enter' on the keyboard on any fields.
This problem gets fixed when I remove my input field of author. Please guide me as I am new to Reactjs
import React, { useState } from "react";
function Create() {
const [title, setTitle] = useState();
const [author, setAuthor] = useState();
const [body, setBody] = useState();
const submitFunc = (e) => {
e.preventDefault();
const blog = { title, body, author };
};
return (
<div className="create container ">
<form onSubmit={submitFunc}>
<label className="text-danger" htmlFor="title">
Title:
</label>
<input
name="title"
type="text"
onChange={(e) => setTitle(e.target.value)}
required
/>
<label className="text-danger" htmlFor="body">
Content:
</label>
<textarea
onChange={(e) => setBody(e.target.value)}
required
name="body"
></textarea>
<label className="text-danger" htmlFor="author">
Author:
</label>
<input
name="author"
id="author"
type="text"
onChange={(e) => setAuthor(e.target.value)}
required
/>
</form>
<p>{title}</p>
<p>{author}</p>
<p>{body}</p>
</div>
);
}
export default Create;
From the snippet you reported it is not clear how it should handle the Enter pressing.
If you want to do anything when the user presses Enter on any text area you can use the onKeyPress event handler.
const handleKeyPress = (e) => {
if(e.keyCode === 13){
e.preventDefault();
// ...check title, boby and author exists
const blog = { title, body, author };
// ...submit the form
};
<textarea
name="body"
required
onChange={(e) => setBody(e.target.value)}
onKeyPress={handleKeyPress}
></textarea>

Problems with Registering User

So, I have a backend auth which is showing me the Userdata in the postman and as well in the Mongo. I had an error in the console xhr.js:177 POST http://localhost:3000/api/auth/register 404 (Not Found) which I think I fixed by adding ""http://localhost:5000/api/auth/register", instead of just api/auth/register in the post method, but now when I try to register I am getting this error Unhandled Rejection (TypeError): Cannot read property 'data' of undefined. If someone would tell me why is this showing, and how to I fix it, I would be grateful. Thanks
import axios from "axios";
import { Link } from "react-router-dom";
const Register = ({ history }) => {
const [username, setUsername] = useState("");
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [confirmpassword, setConfirmPassword] = useState("");
const [error, setError] = useState("");
const registerHandler = async (e) => {
e.preventDefault();
const config = {
header: {
"Content-Type": "application/json",
},
};
if (password !== confirmpassword) {
setPassword("");
setConfirmPassword("");
setTimeout(() => {
setError("");
}, 5000);
return setError("Passwords do not match");
}
try {
const { data } = await axios.post(
"http://localhost:5000/api/auth/register",
{
username,
email,
password,
},
config
);
localStorage.setItem("authToken", data.token);
history.push("/");
} catch (error) {
setError(error.response.data.error);
setTimeout(() => {
setError("");
}, 5000);
}
};
return (
<div className="register-screen">
<form onSubmit={registerHandler} className="register-screen__form">
<h3 className="register-screen__title">Register</h3>
{error && <span className="error-message">{error}</span>}
<div className="form-group">
<label htmlFor="name">Username:</label>
<input
type="text"
required
id="name"
placeholder="Enter username"
value={username}
onChange={(e) => setUsername(e.target.value)}
/>
</div>
<div className="form-group">
<label htmlFor="email">Email:</label>
<input
type="email"
required
id="email"
placeholder="Email address"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
</div>
<div className="form-group">
<label htmlFor="password">Password:</label>
<input
type="password"
required
id="password"
autoComplete="true"
placeholder="Enter password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
</div>
<div className="form-group">
<label htmlFor="confirmpassword">Confirm Password:</label>
<input
type="password"
required
id="confirmpassword"
autoComplete="true"
placeholder="Confirm password"
value={confirmpassword}
onChange={(e) => setConfirmPassword(e.target.value)}
/>
</div>
<button type="submit" className="btn btn-primary">
Register
</button>
<span className="register-screen__subtext">
Already have an account? <Link to="/login">Login</Link>
</span>
</form>
</div>
);
};
export default Register;
you need to check for error.response existence. Seems like it is undefined in your case.
if (error.response) {
setError(error.response.data.error);
}
setTimeout(() => {
setError("");
}, 5000);
That will help you with this error Cannot read property 'data' of undefined but to answer why you're getting xhr.js:177 POST http://localhost:3000/api/auth/register 404 (Not Found) we need more information. Simply there is no /api/auth/register handler on your server.

React Hooks, object state is not updating onSubmit

I am using React Hooks and am created a form to submit blog posts. I am having trouble writing the submitPost logic. I have a post, and setPost variable. setPost doesn't seem to be updating post with the new post in the submitPost function, so my api call function createPost isn't receiving the new req.body. But when I created a second function changePost(), post is updated.
This is my code.
export default function NewPost({ props }) {
const [post, setPost] = useState({
title: "",
img: "",
content: "",
user_id: 0,
});
const [img, setImg] = useState("");
const [title, setTitle] = useState("");
const [content, setContent] = useState("");
const [userId, setUserId] = useState(0);
useEffect(() => {
const handleUser = async () => {
try {
const response = await verifyUser();
console.log(response);
setUserId(response.user.id);
} catch (error) {
console.log(error);
}
};
handleUser();
});
const changePost = () => {
const newPost = {
title: title,
img: img,
content: content,
user_id: userId,
};
setPost(newPost);
console.log(post);
};
const submitPost = async (e) => {
e.preventDefault();
console.log(userId);
try {
console.log(title);
changePost();
console.log("submitPost", post);
await createPost(post);
props.history.push("/posts");
} catch (error) {
console.log(error);
}
};
console.log(post);
return (
<div>
<Nav />
<div class="ui main text container segment mt-100">
<div class="ui huge header salmon">New Blog </div>
<form class="ui form" onSubmit={submitPost}>
<div class="field">
<label> Title </label>
<input
type="text"
name="title"
value={title}
onChange={(e) => setTitle(e.target.value)}
placeholder="title"
/>
</div>
<div class="field">
<label> Image </label>
<input
type="text"
name="img"
value={img}
onChange={(e) => setImg(e.target.value)}
placeholder="image"
/>
</div>
<div class="field">
<label> Body </label>
<textarea
name="content"
value={content}
onChange={(e) => setContent(e.target.value)}
placeholder="blog post goes here"
>
{" "}
</textarea>
</div>
<input class="ui teal big basic button" type="submit" />
</form>
</div>
</div>
);
}
It won't work. You're trying to create a post where your post variable is not yet updated. You don't need to create so many variables, just use the post variable.
Try using the below code.
export default function NewPost({ props }) {
const [post, setPost] = useState({
title: "",
img: "",
content: "",
user_id: 0,
});
useEffect(() => {
const handleUser = async () => {
try {
const response = await verifyUser();
console.log(response);
setPost({...post, user_id: response.user.id});
} catch (error) {
console.log(error);
}
};
handleUser();
});
const submitPost = async (e) => {
e.preventDefault();
console.log(userId);
try {
console.log(title);
console.log("submitPost", post);
await createPost(post);
props.history.push("/posts");
} catch (error) {
console.log(error);
}
};
console.log(post);
return (
<div>
<Nav />
<div class="ui main text container segment mt-100">
<div class="ui huge header salmon">New Blog </div>
<form class="ui form" onSubmit={submitPost}>
<div class="field">
<label> Title </label>
<input
type="text"
name="title"
value={title}
onChange={(e) => setPost({...post, title: e.target.value})}
placeholder="title"
/>
</div>
<div class="field">
<label> Image </label>
<input
type="text"
name="img"
value={img}
onChange={(e) => setPost({...post, img: e.target.value})}
placeholder="image"
/>
</div>
<div class="field">
<label> Body </label>
<textarea
name="content"
value={content}
onChange={(e) => setPost({...post, content: e.target.value})}
placeholder="blog post goes here"
>
{" "}
</textarea>
</div>
<input class="ui teal big basic button" type="submit" />
</form>
</div>
</div>
);
}
just do this .
useEffect(()=>{
},[JSON.stringify(post)])..
setPost({ title,img,content,user_id});

Categories

Resources