Why isn't my React Form sending? - reactjs

I've used this tutorial offline and I have this:
import React from 'react';
import '../Normalize.css';
import '../App.css';
import $ from 'jquery';
class ReactFormLabel extends React.Component {
constructor(props) {
super(props);
}
render() {
return(
<label htmlFor={this.props.htmlFor}>{this.props.title}</label>
)
}
}
class ReactForm extends React.Component {
constructor(props) {
super(props);
this.state = {
name: '',
email: '',
subject: '',
message: ''
}
}
handleChange = (e) => {
let newState = {};
newState[e.target.name] = e.target.value;
this.setState(newState);
};
handleSubmit = (e, message) => {
e.preventDefault();
let formData = {
formSender: this.state.name,
formEmail: this.state.email,
formSubject: this.state.subject,
formMessage: this.state.message
}
if (formData.formSender.length < 1 || formData.formEmail.length < 1 || formData.formSubject.length < 1 || formData.formMessage.length < 1) {
return false;
}
$.ajax({
url: '/some/url',
dataType: 'json',
type: 'POST',
data: formData,
success: function(data) {
if (window.confirm('Thank you for your message. Can I erase the form?'))
{
document.querySelector('.form-input').val('');
}
},
error: function(xhr, status, err) {
console.error(status, err.toString());
alert('There was some problem with sending your message.');
}
});
this.setState({
firstName: '',
lastName: '',
email: '',
subject: '',
message: ''
});
};
render() {
return(
<form className='react-form' onSubmit={this.handleSubmit}>
<fieldset className='form-group'>
<ReactFormLabel htmlFor='formName' title='Full Name:' />
<input id='formName' className='form-input' name='name' type='text' required onChange={this.handleChange} value={this.state.name} />
</fieldset>
<fieldset className='form-group'>
<ReactFormLabel htmlFor='formEmail' title='Email:' />
<input id='formEmail' className='form-input' name='email' type='email' required onChange={this.handleChange} value={this.state.email} />
</fieldset>
<fieldset className='form-group'>
<ReactFormLabel htmlFor='formSubject' title='Subject:'/>
<input id='formSubject' className='form-input' name='subject' type='text' required onChange={this.handleChange} value={this.state.subject} />
</fieldset>
<fieldset className='form-group'>
<ReactFormLabel htmlFor='formMessage' title='Message:' />
<textarea id='formMessage' className='form-textarea' name='message' required onChange={this.handleChange}></textarea>
</fieldset>
<div className='form-group'>
<input id='formButton' className='btn' type='submit' placeholder='Send message' />
</div>
</form>
)
}
};
export default ReactForm;
I think it has something to do with this section:
$.ajax({
url: '/some/url',
dataType: 'json',
type: 'POST',
data: formData,
success: function(data) {
if (window.confirm('Thank you for your message. Can I erase the form?'))
{
document.querySelector('.form-input').val('');
}
With the URL but I'm not too sure where to send it to? Is there something very simple I am overlooking here? It renders fine, it validates fine, it's just not sending. I followed this tutorial: https://blog.alexdevero.com/insanely-easy-simple-react-form-tutorial/
Thanks!

You must bind your functions to the component like so:
class ReactForm extends React.Component {
constructor(props) {
super(props);
this.state = {
name: '',
email: '',
subject: '',
message: ''
}
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
Also, here are the react docs detailing forms: https://facebook.github.io/react/docs/forms.html

Related

this.state not populating fields in editProfile.component

Newbie here. Basic question I know. I have made a 'newProfile' component using pretty much the same mechanics as this and it's working! Now I need an editProfile component that updates the Profile form with props from the database using params.id. The URL shows the .id piece is working when I click 'edit' on a profile in a profileList component that is also working. This code is not getting errors, but it is not showing state for each of the fields.
What am I missing?
`
export default class EditProfile extends Component {
constructor(props) {
super(props);
this.onChangeUsername = this.onChangeUsername.bind(this);
this.onChangeFirst = this.onChangeFirst.bind(this);
this.onChangeLast = this.onChangeLast.bind(this);
this.onChangeEmail = this.onChangeEmail.bind(this);
this.onChangePassword = this.onChangePassword.bind(this);
this.onChangeDob = this.onChangeDob.bind(this);
this.onChangeLocation = this.onChangeLocation.bind(this);
this.onSubmit = this.onSubmit.bind(this);
this.state = {
username: '',
first: '',
last: '',
email: '',
password:'',
dob:'',
location:'',
}
}
componentDidMount() {
axios.get('http://localhost:5000/profiles/'+this.props.match.params.id)
.then(response => {
this.setState({
username: response.data.username,
first: response.data.first,
last: response.data.last,
email: response.data.email,
password: response.data.password,
dob: response.data.dob,
location: response.data.location
})
})
.catch(function (error) {
console.log(error);
})
}
componentDidMount() {
axios.get('http://localhost:5000/users/')
.then(response => {
if (response.data.length > 0) {
this.setState({
users: response.data.map(user => user.username),
})
}
})
.catch((error) => {
console.log(error);
})
}
onChangeProfilePic(e) {
this.setState({
profilePic: e.target.value
});
}
onChangeUsername(e) {
this.setState({
username: e.target.value
});
}
onChangeFirst(e) {
this.setState({
first: e.target.value
});
}
onChangeLast(e) {
this.setState({
last: e.target.value
});
}
onChangeEmail(e) {
this.setState({
email: e.target.value
});
}
onChangePassword(e) {
this.setState({
password: e.target.value
});
}
onChangeDob(e) {
this.setState({
dob: e.target.value
});
} onChangeLocation(e) {
this.setState({
location: e.target.value
});
}
onSubmit(e) {
e.preventDefault();
const profile = {
username: this.state.username,
first: this.state.first,
last: this.state.last,
email: this.state.email,
password: this.state.password,
dob: this.state.dob,
location: this.state.location,
}
console.log(profile);
axios.post('http://localhost:5000/profiles/update'+this.props.match.params.id, profile)
.then(res => console.log(res.data));
window.location = '/';
}
render() {
return (
<div>
<h3>Edit Profile
</h3>
<form onSubmit={this.onSubmit}>
<div className="form-group">
<label>Username:
</label>
<input
type="text"
className="form-control"
value={this.state.username}
onChange={this.onChangeUsername}
/>
</div>
<div className="form-group">
<label>First Name:
</label>
<input
type="text"
className="form-control"
value={this.state.first}
onChange={this.onChangeFirst}
/>
</div>
<div className="form-group">
<label>Last Name:
</label>
<input
type="text"
className="form-control"
value={this.state.last}
onChange={this.onChangeLast}
/>
</div>
<div className="form-group">
<label>Email:
</label>
<input
type="text"
className="form-control"
value={this.state.email}
onChange={this.onChangeEmail}
/>
</div>
<div className="form-group">
<label>Password:
</label>
<input
type="text"
className="form-control"
value={this.state.password}
onChange={this.onChangePassword}
/>
</div>
<div className="form-group">
<input type="submit" value="Save" className="btn btn-primary" />
</div>
</form>
</div>
)}
}
`
Here is the error I'm getting in the console.
react-dom.development.js:86 Warning: A component is changing a controlled input to be uncontrolled. This is likely caused by the value changing from a defined to undefined, which should not happen. Decide between using a controlled or uncontrolled input element for the lifetime of the component. More info: https://reactjs.org/link/controlled-components
at input
at div
at form
at div
at CreateProfile (http://localhost:3000/static/js/bundle.js:194:5)
at RenderedRoute (http://localhost:3000/static/js/bundle.js:44214:5)
at Routes (http://localhost:3000/static/js/bundle.js:44678:5)
at div
at Router (http://localhost:3000/static/js/bundle.js:44609:15)
at BrowserRouter (http://localhost:3000/static/js/bundle.js:42779:5)
at App

Why is React menu pick not maintaining selection?

I am trying to figure out why the menu pick for a note's Folder Name is not getting selected in the code below. I'm using the tags around the folder options. The user can select the Folder Name for the note being created from the UI, but the UI doesn't maintain the selection. As a result, the note is not getting saved to any of the folders.
import React, { Component } from 'react'
import NotesContext from './notesContext'
import './addNote.css'
class AddNote extends Component {
static contextType = NotesContext
constructor(props) {
super(props);
this.state = {
name: '',
value: '',
id: '',
folderId: '',
content: ""
}
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
console.log("handleChange value: " + event.target.value);
console.log("handleChange name: " + event.target.name)
this.setState(
{[event.target.name]: event.target.value}
);
}
handleSubmit(event) {
console.log("this.context: " + JSON.stringify(this.context))
event.preventDefault();
let requestOptions = {
method: 'POST',
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
"name": this.state.name,
"id": this.state.id,
"folderId": this.state.folderId,
"modified": new Date().toISOString(),
"content": this.state.content
})
};
fetch("http://localhost:9090/notes/", requestOptions)
.then(response => response.json())
.then(result => {
console.log("result:" + JSON.stringify(result));
this.context.addNote(
result.name,
result.id,
result.folderId,
result.modified,
result.content
);
this.props.history.push("/");
})
.catch(error => console.log('error', error));
}
render() {
let notesContext = this.context
return (
<form
className="AddNote"
onSubmit={e => this.handleSubmit(e)}
>
<h1>Create a note</h1>
<label>
Note Name:{' '}
<input
type="text"
value={this.state.name}
className="NameInput"
name="name"
id="name"
onChange={(e) => this.handleChange(e)}
/>
</label>
<label>
Content:{' '}
<textarea
className="ContentInput"
name="content"
id="content"
onChange={e => this.handleChange(e)}
/>
</label>
<label>
Folder:{' '}
<select
value={this.state.folderId} onChange={ (e) => this.handleChange(e)}>
{notesContext.folders.map(folder => {
return(
<option
value={folder.name}
name={folder.name}
key={folder.id}>{folder.name}
</option>
)
})}
</select>
</label>
<input
type="submit"
value="Submit"
className="SubmitButton"
/>
</form>
);
}
}
export default AddNote;
I have a partial Answer at this point. I split up the handleChange method for setting the note and folder. This is now allowing me to create the note in the selected folder -- only if I select a new folder, not the folder selected by default. So I still need to fix that part.
import React, { Component } from 'react'
import NotesContext from './notesContext'
import './addNote.css'
class AddNote extends Component {
static contextType = NotesContext
constructor(props) {
super(props);
this.state = {
name: 'Cows',
id: '',
folderId: '',
content: "",
value: '',
}
this.handleChangeOfNote = this.handleChangeOfNote.bind(this);
this.handleChangeOfFolder = this.handleChangeOfFolder.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChangeOfNote(event) {
//console.log("handleChange value: " + event.target.value);
//console.log("handleChange name: " + event.target.name);
this.setState(
{[event.target.name]: event.target.value}
);
}
handleChangeOfFolder(event) {
this.setState(
{folderId: event.target.value}
);
}
handleSubmit(event) {
event.preventDefault();
let requestOptions = {
method: 'POST',
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
"name": this.state.name,
"id": this.state.id,
"folderId": this.state.folderId,
"modified": new Date().toISOString(),
"content": this.state.content
})
};
fetch("http://localhost:9090/notes/", requestOptions)
.then(response => response.json())
.then(result => {
console.log("result:" + JSON.stringify(result));
this.context.addNote(
result.name,
result.id,
result.folderId,
result.modified,
result.content
);
this.props.history.push("/");
})
.catch(error => console.log('error', error));
}
render() {
let notesContext = this.context
return (
<form
className="AddNote"
onSubmit={e => this.handleSubmit(e)}
>
<h1>Create a note</h1>
<label>
Note Name:{' '}
<input
type="text"
value={this.state.name}
className="NameInput"
name="name"
id="name"
onChange={(e) => this.handleChangeOfNote(e)}
/>
</label>
<label>
Content:{' '}
<textarea
className="ContentInput"
name="content"
id="content"
onChange={e => this.handleChangeOfNote(e)}
/>
</label>
<label>
Folder:{' '}
<select
value={this.state.folderId} onChange={(e) => this.handleChangeOfFolder(e)}>
{notesContext.folders.map(folder => {
return(
<option
value={folder.id}
name={folder.name}
key={folder.id}>{folder.name}
</option>
)
})}
</select>
</label>
<input
type="submit"
value="Submit"
className="SubmitButton"
/>
</form>
);
}
}
export default AddNote;
To fix the problem with the default folder getting set, for now I just set the folderId in state, so that it would be there by default.
constructor(props) {
super(props);
this.state = {
name: '',
id: '',
folderId: 'b0715efe-ffaf-11e8-8eb2-f2801f1b9fd1',
content: "",
value: '',
}

Extra undefined value in this.state

i am trying to post a form in reactjs, and i suspect it doesnt write to DB because i get strange undefined in my state, which looks like:
form looks like this
but in console i get:
this
my code on front is :
constructor(props) {
super(props);
this.state = { name: '', gender: '', email: '' };
}
handleChange= (event) => {
this.setState({
[event.target.name]: event.target.value,
[event.target.gender]: event.target.value,
[event.target.email]: event.target.value,
// [event.target.phone]: event.target.value,
});
}
handleSubmit = (event) => {
console.log(JSON.stringify(this.state));
alert('A form was submitted: ' + this.state);
fetch('http://localhost:3000/api/game/contacts', {
method: 'POST',
body: JSON.stringify(this.state)
}).then(function(response) {
return response.json();
});
event.preventDefault();
}
render() {
const { user } = this.props.auth;
console.log(this.state);
return(
<div>
<form onSubmit={this.handleSubmit}>
<label>
Name:</label>
<input type="text" value={this.state.value} name="name" onChange={this.handleChange} />
<label>
Gender:</label>
<input type="text" value={this.state.value} name="gender" onChange={this.handleChange} />
<label>
Email:</label>
<input type="text" value={this.state.value} name="email" onChange={this.handleChange} />
<input type="submit" value="Submit" />
</form>
</div>
);
}
}
Dashboard.propTypes = {
auth: PropTypes.object.isRequired
};
const mapStateToProps = ( state ) => ({
auth: state.auth
});
export default connect( mapStateToProps )( Dashboard );
must be super simple, but i googled for 2 hours, and could not see issue. Thanks for you time

React signup page syntax error at return of render function

i have a react sign up page that returns an error at the return of the render method. It shows a syntax error whenever i run the code on the browser. The code is meant to pass data to a server endpoint.I have looked all over and can't find the cause of the error. I would like to know the probable cause of this problem and the line of action or code to correct this error
`import React, { Component } from 'react';
class Register extends Component {
constructor(props) {
super(props);
this.state = {
name:'',
town: '',
long: '',
lat: ''
}
}
handleChange = (e) => {
this.setState({
[e.target.name]: e.target.value
})
}
onSubmit = (e) => {
e.preventDefault();
const Register = {
name: this.state.name,
town: this.state.town,
long: this.state.long,
lat: this.state.lat
}
}
}
fetch ('https://localhost3000/users/', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'name',
city: 'city',
long: 'long',
lat: 'lat'
})
})
.then(function(response){
return response.json();
})
.then(function(Register){
console.log(Register)
});
*render() {
return ( *
<div>
<form className="form-style">
<label>
Name:<br/>
<input name='name' value={this.state.name}
placeholder="Enter Your Farm Name"
onChange={e => this.handleChange(e)}/>
</label><br/>
<label>
Town:<br/>
<input name='town' value={this.state.town}
placeholder="Enter town where farm is located"
onChange={e => this.handleChange(e)}/>
</label><br/>
<label>
Longitude:<br/>
<input name='long' value={this.state.long}
placeholder="Enter Your Farm Longitude"
onChange={e => this.handleChange(e)}/><br/>
Latitude:<br/>
<input name='lat' value={this.state.lat}
placeholder="Enter Your Farm Latitude"
onChange={e => this.handleChange(e)}/>
</label><br/>
<Link><a href="https://www.latlong.net/" target="_blank">
Get Longitude and Latitude of current location here</a></Link><br/>
<button onClick={e => this.handleSubmit(e)}
disabled={!this.state.name}
disabled={!this.state.long}
disabled={!this.state.lat}
disabled={!this.state.town}>
Register</button>
</form>
</div>
)
};
export default Register ;`
You have a misplaced } in your code right after you define the onSubmit function. This closed off your component and made the rest of your code invalid. You're also trying to call fetch inside your component without it being inside any lifecycle-method, function or event. This will lead to a syntax error.
Try this instead :)
import React from "react"
import { Link } from "react-router-dom"
class Register extends React.Component {
constructor(props) {
super(props)
this.state = {
name:'',
town: '',
long: '',
lat: ''
}
}
handleChange = (e) => {
this.setState({
[e.target.name]: e.target.value
})
}
componentDidMount(){
fetch ('https://localhost3000/users/', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'name',
city: 'city',
long: 'long',
lat: 'lat'
})
})
.then(function(response){
return response.json();
})
.then(function(Register){
console.log(Register)
})
}
onSubmit = (e) => {
e.preventDefault()
const Register = {
name: this.state.name,
town: this.state.town,
long: this.state.long,
lat: this.state.lat
}
}
render(){
return (
<div>
<form className="form-style">
<label>
Name:<br/>
<input name='name' value={this.state.name}
placeholder="Enter Your Farm Name"
onChange={e => this.handleChange(e)}/>
</label><br/>
<label>
Town:<br/>
<input name='town' value={this.state.town}
placeholder="Enter town where farm is located"
onChange={e => this.handleChange(e)}/>
</label><br/>
<label>
Longitude:<br/>
<input name='long' value={this.state.long}
placeholder="Enter Your Farm Longitude"
onChange={e => this.handleChange(e)}/><br/>
Latitude:<br/>
<input name='lat' value={this.state.lat}
placeholder="Enter Your Farm Latitude"
onChange={e => this.handleChange(e)}/>
</label><br/>
<Link><a href="https://www.latlong.net/" target="_blank">
Get Longitude and Latitude of current location here</a></Link><br/>
<button onClick={e => this.handleSubmit(e)}
disabled={!this.state.name}
disabled={!this.state.long}
disabled={!this.state.lat}
disabled={!this.state.town}>
Register</button>
</form>
</div>
)
}
}
export default Register

State Value Not Being Set from Default Value on Form Submission

I have a form where two of my input fields have a defaultValue set to prop values. On form submission I am passing the values from other inputs that are set to state properties, but I am not sure how to capture the defaultValue if the values from those two input fields remain unchanged. Is there a method that follows best practices to capture the defaultValue if the value never changes?
import React from 'react';
import { API_ROOT } from '../../../../config/api-config';
//Annotation - Footer - Email Annotation Modal
export default class EmailAnnotationForm extends React.Component {
constructor(props) {
super(props);
this.state = {
csrf: '',
subject: '',
emails: '',
comment: ''
}
this.handleInputChange = this.handleInputChange.bind(this);
this.handleFormSubmit = this.handleFormSubmit.bind(this);
this.handleClearForm = this.handleClearForm.bind(this);
}
handleInputChange(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
console.log(event);
this.setState({
[name]: value
});
console.log(target)
console.log(name)
console.log(value)
console.log(JSON.stringify(this.state));
}
handleFormSubmit(event) {
console.log("handleFormSubmit")
const body = {
csrf: this.state.csrf,
subject: this.state.subject,
emails: this.state.emails,
comment: this.state.comment
};
event.preventDefault();
var route = `${API_ROOT}` + '/api/annotation/' + this.props.annotationId + '/share/email';
fetch(route,
{
method: 'POST',
body: JSON.stringify(body),
compress: false,
headers: {
'X-CSRF-Token': this.state.csrf,
'Accept': 'application/json',
'Content-Type': 'application/json'
}
})
.then(res => {
return res.json();
})
.then(data => {
console.log(data)
handleClearForm()
this.setState({'flash': 'success'});
})
.catch(err => {
console.log(err);
this.setState({'flash': 'error'});
});
}
handleClearForm() {
console.log("handleClearForm")
this.setState({
csrf: '',
subject: '',
emails: '',
comment: ''
})
}
render() {
return (
<div className="annotation-footer__share-form-email">
<form action={"/api/annotation/" + this.props.annotationId + "/share/email"} method="post" onSubmit={this.handleFormSubmit} name="annotationEmailShare" id="share-email-form">
<input type="hidden" name="_csrf" defaultValue={this.props.csrf ? this.props.csrf : ""}/>
<div className="input-group annotation-footer__share-form-email-inputs">
<p><b>Subject:</b></p>
<input type="text" name="subject" className="form-control" defaultValue={this.props.title} onChange={this.handleInputChange}/><br />
</div>
<div className="input-group annotation-footer__share-form-email-inputs">
<p><b>Emails (Comma separate each eamil address):</b></p>
<input type="text" name="emails" className="form-control" onChange={this.handleInputChange}/><br />
</div>
<div className="input-group annotation-footer__share-form-email-inputs">
<p><b>Additional Comment:</b></p>
<textarea name="comment" rows="4" className="form-control" onChange={this.handleInputChange}>{this.state.comment}</textarea><br />
</div>
<button type="submit">Send Email</button>
</form>
</div>
)
}
}
Inputs with DefaultProps:
<input type="hidden" name="_csrf" defaultValue={this.props.csrf ? this.props.csrf : ""}/>
<input type="text" name="subject" className="form-control" defaultValue={this.props.title} onChange={this.handleInputChange}/>
Submitted Value (csrf and subject are not appearing with defaultValues):
{"csrf":"","subject":"","emails":"test#gmail.com","comment":"dsfsdfadsfs"}

Resources