In my React application, I have a form with only username and password (later I will add "confirm password" as well), when submitting a request with JSON should be send that contains the email and password in its body.
Password can only be accepted after few checks and if it passes all of those conditions then it will be accepted.
render() {
return (
<form className="demoForm" onSubmit={this.handleUserInput} >
.
.
.
.
<button type="submit" className="btn btn-primary" disabled={!this.state.formValid}>Sign U p</button>
</form>
);
}
handleUserInput = (e) => {
const name = e.target.name;
const value = e.target.value;
this.setState({[name]: value}, () => { this.validateField(name, value) });
axios.post('****', {
value
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
}
I am using axios like above, my problem is that I dont know what should be instead of this ****, I am using local host. Is this a good way to do this?
You should add the address you are posting your call to. (i.e. /api/validate_user)
Just on a side note, try separating your actions.
onChangeHandler(e) {
e.preventDefault()
const { value, id} = e.target
this.setState({
[id]: value
})
}
to update the state and then to submit
onSubmitHandler(e) {
var self = this;
e.preventDefault()
const { userName, password } = this.state;
// Do validation of password
axios.post('/api/validateUser', {
user: userName,
password: password
}).then(e => {
if(e.success){
console.log("success")
}
else if(e.error) {
console.log("error logging in")
}
})
}
Related
I've built a contact form and I'm trying to get my user inputted values to post using axios so I then get an email with the data inputted by the user.
I keep getting undefined values in my emails being sent. My server side is fine, I'm not to worried about that. What's the best approach for this?
document.querySelector(".contact-btn").addEventListener("click", sendIt);
function sendIt(event) {
event.preventDefault();
axios
.post("https://us-central1-selexin-website.cloudfunctions.net/app/sendemail", {
name: "",
email: "",
number: "",
message: "",
})
.then((res) => {
console.log(res);
});
}
this might work, also you can re-read documentation on POST Request Axios Documentation
For Live view how it works you can check on CODEPEN
const form = document.querySelector("form")
const input = document.querySelector("input")
const submitUser = () => {
axios.post('https://us-central1-selexin-website.cloudfunctions.net/app/sendemail', {
firstName: input.value,
})
.then(response => {
console.log(response);
})
.catch(error => {
console.log(error);
});
}
form.addEventListener("submit", (e) => {
submitUser()
e.preventDefault()
})
<form>
<input type="text">
<button type="submit">Submit</button>
</form>
I want to add some company details to mongo DB, and the details include a company logo. So I want to upload the picture to Cloudinary and then save the URL in Mongo DB with the other details.
But my code doesn't seem to work. When I fill the form and click on submit, the image gets uploaded to Cloudinary but it does not get saved in the Database.
To store the image
const [ companyLogo, setCompanyLogo] = useState("");
const [ companyLogoURL, setCompanyLogoURL] = useState("");
Function to execute on submit
const handleCompanySubmit = (evt) => {
evt.preventDefault();
const data = new FormData()
data.append("file", companyLogo)
data.append("upload_preset", "Sprint")
data.append("cloud_name", "sprint-ccp")
fetch("https://api.cloudinary.com/v1_1/sprint-ccp/image/upload",{
method:"post",
body:data
})
.then(res => res.json())
.then(data => {
setCompanyLogoURL(data.url)
})
.catch(err => {
console.log(err)
})
//check for empty fields
if (
isEmpty(companyName) ||
isEmpty(companyAddress) ||
isEmpty(companyRegNumber) ||
isEmpty(companyContactNumber)
) {
setCompanyErrorMsg("Please Fill All The Fields");
}else {
let formData = new FormData();
formData.append('companyName', companyName);
formData.append('companyAddress', companyAddress);
formData.append('companyRegNumber', companyRegNumber);
formData.append('companyContactNumber', companyContactNumber);
formData.append('companyLogo', companyLogoURL);
setCompanyLoading(true);
addCompany(formData)
.then((response) => {
setCompanyLoading(false);
setCompanySuccessMsg(response.data.successMsg)
setCompanyData({
companyName: "",
companyAddress: "",
companyRegNumber: "",
companyContactNumber: ""
});
})
.catch((err) => {
setCompanyLoading(false);
setCompanyErrorMsg(err.response.data.errorMsg)
})
}
};
const handleCompanyLogo = (evt) => {
setCompanyLogo(evt.target.files[0])
};
frontend view
<form className="register-form" onSubmit={handleCompanySubmit} noValidate>
<label className="text-secondary">Company Logo :</label>
<input type="file" className="form-control" onChange={handleCompanyLogo}/>
//remaining input fields
<button className="btn btn-info submitButton" >Submit</button>
</form>
api for adding company
export const addCompany = async (data) => {
const config = {
headers: {
"Content-Type": "application/json",
},
};
const response = await axios.post(
"http://localhost:5000/api/auth/clients/company",
data,
config
);
return response;
};
controller in backend
exports.addNewCompany = async(req,res)=>{
const {
companyName,
companyAddress,
companyRegNumber,
companyContactNumber,
companyLogo
} = req.body;
const company = await Company.findOne({ companyName });
if (company) {
return res.status(400).json({
errorMsg: `${req.body.companyName} already exists`,
});
}
try{
const newCompany = new Company();
newCompany.companyName = companyName;
newCompany.companyAddress = companyAddress;
newCompany.companyRegNumber = companyRegNumber;
newCompany.companyContactNumber = companyContactNumber;
newCompany.companyLogo = companyLogo;
await newCompany.save();
res.json({
successMsg: `${req.body.companyName} Company Added Successfully`
});
} catch (err) {
console.log("clientsController error - Add Company ", err);
res.status(500).json({
errorMsg: "Server Error. Please Try again",
});
}
};
The error i get in the console is this
clientsController error - Add Company Error: Company validation failed: companyLogo: Path companyLogo is required.
at ValidationError.inspect
(C:\CCP\sd08_2021\Backend\node_modules\mongoose\lib\error\validation.js:47:26)
Can you please help me out ?
I think that your error is caused by a more trivial problem :
When you send the POST request with fetch, you don't actually wait for its completion (it's a promise), so the code in the if ... else {...} statement is executed before the termination of the fetch() !
setCompanyLogoURL(data.url) has not been called yet, so formData.append('companyLogo', companyLogoURL); set a blank string instead of the value returned by the call to the Cloudinary API.
The solution would be to make handleCompanySubmit async, and to await for the fetch() promise completion.
Hi Please help a struggling dev.
I have been trying all day to get this fixed to no avail. Essentially all I want to to do is post from my AddUsers class and for this to be stored through to my sql database. It is a very simple query but has gotten the better off me!The state is updated on change but seems to be an issue with the server.js (error included at bottom of post)
Server.js
app.post("/admin-Add-Users", function(req, res) {
var request = new sql.Request();
// query to the database and get the records
request.query(
"insert into Login (email, password) values ('" +
req.body.email +
"','" +
req.body.password +
"')",
function(err, recordset) {
if (err) console.log(err);
}
);
res.send({ message: "Success" });
});
AddUsers class
class AddUsers extends React.Component {
constructor() {
super();
this.state = { users: [], email: "", password: "" };
this.onSubmit = this.handleSubmit.bind(this);
}
handleSubmit(e) {
e.preventDefault();
const data = { email: this.state.email, password: this.state.password };
fetch("/admin-Add-Users", {
method: "POST", // or 'PUT'
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(data)
})
.then(response => response.json())
.then(data => {
console.log("Success:", data);
})
.catch(error => {
console.error("Error:", error);
});
}
render() {
console.log(this.state.users);
return (
<div>
<LoginForm></LoginForm>
<form>
<input
type="text"
placeholder="email"
value={this.state.email}
onChange={e => this.setState({ email: e.target.value })}
/>
<input
type="text"
placeholder="password"
value={this.state.password}
onChange={e => this.setState({ password: e.target.value })}
/>
<input type="submit" onClick={this.onSubmit} />
</form>
</div>
);
}
}
ReferenceError: email is not defined
UPDATE: After trying recommendations I have been given I now revive a new error.
Error: SyntaxError: Unexpected token < in JSON at position 0
It seems like there is nothing wrong in your React app.
The problem is at your API end where you're formulating an insert query without actually reading the request json content (email & password) fields.
You could add following lines before the query is being generated.
// create sql obj
...
var email = req.body.email;
var password = req.body.password;
...
// your query
You need to add middleware to your express app to be able to parse request body's.
Try adding this to the file where you configure express:
app.use(express.json());
email and password fields must be retrieved from req
This is not a complete answer but it turns out the issue is related to CORS. I am not sure of the solution at this point ,but I am fairly sure this is the cause.
Thanks for all your help :)
Hi Everyone thanks for all your help. I fixed this issue by using the following code within my server.js
app.post("/admin-Add-Users", async (req, response) => {
sql.connect(config, function(err) {
if (err) {
console.log(err);
response.status(400);
response.send(err);
} else {
try {
// create Request object
var request = new sql.Request();
var body = req.body;
console.log(body);
if (body) {
var email = body.email;
var password = body.password;
var queryString = `insert into Login (email,password) values ('${email}', '${password}')`;
console.log(queryString);
request.query(queryString, function(err, recordset) {
console.log(err);
response.status(400);
// response.send(err);
});
response.status(201);
response.send("User added ");
} else {
response.status(400);
response.send("no content was provided");
}
} catch (e) {
console.log(e);
response.status(400);
response.send(e);
}
}
});
});
I'm having a problem with sending an authorization header with a graphql request when a user signs up with my react app.
My flow is:
User signs up with Firebase, react app receives id token.
User is redirected to another page where they can fill out more information.
User clicks submit, a request is sent via graphql (Apollo) to custom backend to create user.
The problem is when the user clicks submit on the secondary sign up page to enter their name, the request that is sent to the backend does not contain the authorization header. If I reload that page before clicking submit (this is after firebase sign up was successful), then it works as expected.
index.js:
const token = localStorage.getItem(AUTH_TOKEN);
const client = new ApolloClient({
link: new HttpLink({
uri: 'http://localhost:9000/graphql',
headers: {
authorization: token ? `Bearer ${token}` : ''
}
}),
cache: new InMemoryCache()
});
App.js:
componentWillMount() {
const _this = this;
firebaseApp.auth().onAuthStateChanged((user) => {
if (user) {
console.log('AUTH STATE CHANGED', user);
// If logged in...
_this.setState({ loggedin: true });
user.getToken()
.then((result) => {
localStorage.setItem(AUTH_TOKEN, result);
});
} else {
// If not logged in...
_this.setState({ loggedin: false });
}
});
}
SignUp.js (this is where the user can authenticate with firebase):
handleSubmit(e) {
e.preventDefault()
const email = this.state.email.trim()
const password = this.state.password.trim()
if (isEmail(email)) {
firebaseApp
.auth()
.createUserWithEmailAndPassword(email, password)
.then(() => {
browserHistory.push('/signupcontinued');
})
.catch((error) => {
// Handle Errors here.
const errorMessage = error.message
alert(`errorMessage: ${ errorMessage}`)
})
} else {
alert('Email Address in not valid')
}
}
SignUpContinued.js (where the user enters their name before sending create user request to custom backend):
const SignUpMutation = gql`
mutation CreateUser($userInput: UserInput!) {
user {
create(organizationId: 3, userInput: $userInput) {
id
firstName
lastName
email
organizationId
balance
}
}
}
`
class SignupContinued extends Component {
render() {
let firstname;
let lastname;
return (
<div>
<Mutation mutation={SignUpMutation}>
{(signup, { data }) => (
<div>
<form
onSubmit={e => {
e.preventDefault();
const userInput = {
firstName: firstname.value,
lastName: lastname.value,
email: (firebaseApp.auth().currentUser) ? firebaseApp.auth().currentUser.email : ''
}
signup({ variables: {
userInput
}}).then(() => {
browserHistory.push('/home')
});
firstname.value = '';
lastname.value = '';
}}
>
<input
placeholder='Enter First name'
ref={node => {
firstname = node;
}}
/>
<input
placeholder='Enter Last name'
ref={node => {
lastname = node;
}}
/>
<button type='submit'>Submit</button>
</form>
</div>
)}
</Mutation>
</div>
)
}
}
Am I correctly redirecting the user so that react reloads (and the ApolloClient updates its headers? Or is the issue something to do with my .then functions and onAuthStateChanged isn't done running before the redirect?
Thanks!
Apollo client gets token data from localStorage before firebase set token to localstorage. you should refresh apollo header after firebase setup
I have this function to log in by facebook method in firebase with React Native :
async handleFacebookButton() {
const navigation = this.props.navigation;
const { type, token } = await Facebook.logInWithReadPermissionsAsync(FACEBOOK_APP_ID, {
permissions: ['public_profile', 'email']
});
if (type === 'success') {
const credential = firebase.auth.FacebookAuthProvider.credential(token);
navigation.navigate("Profile");
auth.signInWithCredential(credential).catch(error => {
this.setState({ errorMessage: error.message });
alert('please check your email or password');
});
}
}
And I need to get the user data when login, like username, phone, email.
how can I get the data?
You need a .then() in your auth.signInWithCredential(). Then you'd have something like:
auth.signInWithCredential().then(user => {
// user is the signed in user, for which you can get details
})