I am pretty new to react/redux I am pretty confused with this simple form.My error state is always undefined eventhough I am getting the error data from node js server Without error data I can't set my state.
routes/users.js
import express from 'express';
import Validator from 'validator';
import isEmpty from 'lodash/isEmpty'
let router = express.Router();
function ValidateInput(data) {
let errors = {};
if(isEmpty(data.email)){
errors.email = 'This fiels is required'
}
if(!Validator.isEmail(data.email)){
errors.email = "Email is in Valid"
}
if(isEmpty(data.password)){
errors.password = 'This fiels is required'
}
if(isEmpty(data.passwordConfirmation)){
errors.passwordConfirmation = 'This fiels is required'
}
if(!Validator.equals(data.password,data.passwordConfirmation)){
errors.passwordConfirmation = "Password Must Macthc"
}
if(isEmpty(data.timezone)){
errors.timezone = 'This fiels is required'
}
return{
errors,
isValid:isEmpty(errors)
}
}
router.post('/',(req,res) => {
console.log(req)
const {errors,isValid} = ValidateInput(req.body);
if(!isValid){
res.status(400).json(errors)
}
});
export default router
SignupForm.js
import React from 'react';
import timezones from '../../data/timezone';
import map from 'lodash/map';
class SignupForm extends React.Component {
constructor(props){
super(props);
this.state = {
username:'',
email:'',
password:'',
passwordConfirmation:'',
timezone:'',
errors:{}
};
this.onChange = this.onChange.bind(this);
this.onSubmit = this.onSubmit.bind(this)
}
onChange(e){
this.setState({ [e.target.name]:e.target.value })
}
onSubmit(e){
e.preventDefault();
this.setState({ errors:{} });
this.props.userSignupRequest(this.state).then(function (data) {
console.log(data)//Nothing
// this.setState({
// errors:data
// })
})
}
render(){
console.log(this.state)
const options = map(timezones,(val,key) =>
<option key={val} value={val}>{key}</option>
);
return(
<form onSubmit={this.onSubmit}>
<h1>Join our community</h1>
<div className="form-group">
<label className="control-label">Username</label>
<input
type="text"
name="username"
className="form-control"
value={this.state.username}
onChange={this.onChange}
/>
</div>
<div className="form-group">
<label className="control-label">Email</label>
<input
type="text"
name="email"
className="form-control"
value={this.state.email}
onChange={this.onChange}
/>
</div>
<div className="form-group">
<label className="control-label">Password</label>
<input
type="password"
name="password"
className="form-control"
value={this.state.password}
onChange={this.onChange}
/>
</div>
<div className="form-group">
<label className="control-label">passwordConfirmation</label>
<input
type="password"
name="passwordConfirmation"
className="form-control"
value={this.state.passwordConfirmation}
onChange={this.onChange}
/>
</div>
<div className="form-group">
<label className="control-label">Time Zone</label>
<select
className="form-control"
name="timezone"
onChange={this.onChange}
value={this.state.timezone}
>
<option value="" disabled>Choose Your Timezone</option>
{options}
</select>
</div>
<div className="form-group">
<button className="btn btn-primary btn-lg">
SignUp
</button>
</div>
</form>
)
}
}
SignupForm.propTypes ={
userSignupRequest:React.PropTypes.func.isRequired
};
export default SignupForm
You need to use catch... so
onSubmit(e){
e.preventDefault();
this.setState({ errors:{} });
this.props.userSignupRequest(this.state)
.then(function (data) {
//Success here
})
.catch(({response}) => console.log(response.data)) //Here you get your errors
})
}
Related
I have blockchain application and created Reactjs interface to send data from user to application but when i enter data and try send it get error as follow , any one can help me?
The error is :
XHR POST http://localhost:3000/api/MedicalRecord
[HTTP/1.1 422 Unprocessable Entity 19ms]
The App.js file as follow
import React, { Component } from 'react';
import PostForm from './PostForm'
function App() {
return (
<div className="App">
<PostForm></PostForm>
</div>
);
}
export default App;
The PostForm.js file as follow
import React, { Component } from 'react'
import axios from 'axios'
class PostRecords extends Component {
constructor(props){
super(props)
this.state = {
record_Id: "",
patient: "",
doctor: "",
description: "",
prescription: ""
}
}
handleChange =(e) =>{
this.setState({
[e.target.name]: e.target.value
})
}
handleSubmit = (e) => {
e.preventDefault()
axios.post('http://localhost:3000/api/MedicalRecord')
.then(response =>{
console.log(response)
})
}
render() {
const {record_id, patient, doctor, description, prescription} = this.state
return (
<div>
<form onSubmit={this.handleSubmit}>
<div>
<label>record_id :</label>
<input
type='text'
name ='record_id'
value={record_id}
onChange={this.handleChange}
></input>
</div>
<div>
<label>patient :</label>
<input
type='text'
name ='patient'
value={patient}
onChange={this.handleChange}
></input>
</div>
<div>
<label>doctor :</label>
<input
type='text'
name ='doctor'
value={doctor}
onChange={this.handleChange}
></input>
</div>
<div>
<label>description :</label>
<input
type='text'
name ='description'
value={description}
onChange={this.handleChange}
></input>
</div>
<div>
<label>prescription :</label>
<input
type='text'
name ='prescription'
value={prescription}
onChange={this.handleChange}
></input>
</div>
<button type='submit'>Submit Now</button>
</form>
</div>
)
}
}
export default PostRecords
I am following along with this tutorial (https://medium.com/#beaucarnes/learn-the-mern-stack-by-building-an-exercise-tracker-mern-tutorial-59c13c1237a1) and am trying to print to console through the onSubmit function but this is not occurring and I do not know why. I've made sure to use the bind method, and everything seems to be referenced correctly. What am I missing here?
import React, {Component} from 'react';
import DatePicker from 'react-datepicker';
import "react-datepicker/dist/react-datepicker.css";
export default class CreateWorkout extends Component {
constructor(props) {
super(props); // Refers to the parent class constructorq
this.onChangeUsername = this.onChangeUsername.bind(this);
this.onChangeDescription = this.onChangeDescription.bind(this);
this.onChangeReps = this.onChangeReps.bind(this);
this.onChangeDuration = this.onChangeDuration.bind(this);
this.onChangeDate = this.onChangeDate.bind(this);
this.onSubmit = this.onSubmit.bind(this);
this.state = {
username:'',
description: '',
reps: 0,
duration: 0,
date: new Date(),
users: []
}
}
componentDidMount() { // Invoked immediately after a component is mounted
this.setState({
users: ['test user'],
username: 'test user'
});
}
onChangeUsername(e) {
this.setState({
username: e.target.value
});
}
onChangeDescription(e) {
this.setState({
description: e.target.value
});
}
onChangeReps(e) {
this.setState({
reps: e.target.value
});
}
onChangeDuration(e) {
this.setState({
duration: e.target.value
});
}
onChangeDate(date) { // Need to add a date picker library for this
this.setState({
date: date
});
}
// Submit method for submitting an event of the form...
onSubmit(e) {
e.preventDefault();
const workout = {
username: this.state.username,
description: this.state.description,
reps: this.state.reps,
duration: this.state.duration,
date: this.state.date,
};
console.log(workout);
window.location = '/'; // After form is submitted, the location is updated so the user is taken back to the home page
}
render() {
return (
<div>
<h3>Create New Workout Log</h3>
<form onSubmit={this.onSubmit}>
<div className="form-group">
<label>Username: </label>
<select ref="userInput" required className="form-control" value={this.state.username} onChange={this.onChangeUsername}>
{
this.state.users.map(function(user) {
return <option key={user} value={user}>{user}</option>;
})
}
</select>
</div>
<div className="form-group">
<label>Description: </label>
<input type="text" required className="form-control" value={this.state.description} onChange={this.onChangeDescription}/>
</div>
<div className="form-group">
<label>Reps: </label>
<input type="text" className="form-control" value={this.state.reps} onChange={this.onChangeReps}/>
</div>
<div className="form-group">
<label>Duration: </label>
<input type="text" className="form-control" value={this.state.duration} onChange={this.onChangeDuration}/>
</div>
<div className="form-group">
<label>Date: </label>
<div><DatePicker selected={this.state.date} onChange={this.state.onChangeDate}/></div>
</div>
<div className="form-group">
<input type="submit" value="Create Workout Log" className="btn btn-primary"/>
</div>
</form>
</div>
);
}
}
This is my jsx for the form
import React, { Component } from "react";
import { createUser } from "../HTTPRequests";
import PhoneInput from "react-phone-number-input";
class UserRegForm extends Component {
constructor(props) {
super(props);
this.state = {
email: "",
password: "",
secondPassword: "",
username: "",
phone: "",
current: 0
};
this.handleEmail = this.handleEmail.bind(this);
this.handlePassword = this.handlePassword.bind(this);
this.handleSecondPassword = this.handleSecondPassword.bind(this);
this.handleUsername = this.handleUsername.bind(this);
this.renderSecondPassword = this.renderSecondPassword.bind(this);
this.handleKeyDown = this.handleKeyDown.bind(this);
this.handlePhone = this.handlePhone.bind(this);
}
handleEmail(event) {
this.setState({ email: event.target.value });
}
handlePassword(event) {
this.setState({ password: event.target.value });
}
handleSecondPassword(event) {
this.setState({ secondPassword: event.target.value });
}
handleUsername(event) {
this.setState({ username: event.target.value });
}
handlePhone(phone) {
this.setState({ phone: phone.value });
}
renderSecondPassword() {
var classN;
if (
this.state.secondPassword.length === 0 ||
this.state.secondPassword === this.state.password
) {
classN = "form-control";
} else {
classN = "form-control is-invalid";
}
return (
<div className="form-group">
<label htmlFor="InputPassword2">Introduza novamente a Password</label>
<input
onKeyDown={this.handleKeyDown}
onChange={this.handleSecondPassword}
type="password"
className={classN}
id="InputPassword2"
/>
</div>
);
}
handleKeyDown(event) {
if (event.key === "Enter") {
this.handleSubmit();
}
}
handleSubmit() {
createUser(this.state.email, this.state.password, this.state.username).then(
function(r) {
console.log(r);
}
);
}
render() {
return (
<div className="position-relative m-4">
<form>
<div className="form-group">
<label htmlFor="exampleInputUsername">Nome Completo</label>
<input
onKeyDown={this.handleKeyDown}
onChange={this.handleUsername}
type="username"
className="form-control"
id="exampleInputUsername"
/>
</div>
<div className="form-group">
<label htmlFor="exampleInputEmail1">E-mail</label>
<input
onKeyDown={this.handleKeyDown}
onChange={this.handleEmail}
type="email"
className="form-control"
id="exampleInputEmail1"
aria-describedby="emailHelp"
/>
<small id="emailHelp" className="form-text text-muted">
Nunca partilharemos o seu e-mail com ninguém.
</small>
</div>
<PhoneInput
placeholder="Enter phone number"
value={this.state.phone}
onChange={phone => this.handlePhone({ phone })}
/>
<div className="form-group">
<label htmlFor="InputPassword1">Password</label>
<input
onKeyDown={this.handleKeyDown}
onChange={this.handlePassword}
type="password"
className="form-control"
id="InputPassword1"
/>
</div>
{this.renderSecondPassword()}
<button
type="button"
className="btn btn-primary"
onClick={this.handleSubmit}
>
Submit
</button>
</form>
</div>
);
}
}
export default UserRegForm;
And this is the result...
as you can see the flag just expands to the whole screen.
I have programming experience (C and java), but just started learning HTML and React... So i'm still a bit lost. do I have to wrap the phone number component in something so it behaves? According to documentation the flag should be to the left of the input and not below
Any help is very appreciated
As someone who just encountered the same issue as OP after an update, the fix was very simple:
import 'react-phone-number-input/style.css'
According to last version of the docs : https://github.com/catamphetamine/react-phone-number-input
This is my SearchForm.js, handleKeywordsChange must handle input keywords changes
import React from 'react';
import ReactDOM from 'react-dom';
class SearchForm extends React.Component {
constructor(props) {
super(props)
this.state = {
keywords: '',
city: '',
date: ''
}
//this.handleChange = this.handleChange.bind(this)
//this.handleSubmit = this.handleSubmit.bind(this)
this.handleKeywordsChange = this.handleKeywordsChange.bind(this);
}
handleKeywordsChange(e) {
console.log(1);
this.setState({
value: e.target.value
});
}
render() {
return (
<form className='form search-form' onSubmit={this.handleSubmit}>
<div className="form-row">
<div className="form-group col-md-5">
<label htmlFor="keywords">Keywords</label>
<input type="text" className="form-control" name="keywords" id="keywords" placeholder="Keywords" onChange={this.handleKeywordsChange} value={this.state.keywords} />
</div>
<div className="form-group col-md-5">
<label htmlFor="city">City</label>
<input type="text" className="form-control" name="city" id="city" placeholder="City" onChange={this.handleChange} value={this.state.city} />
</div>
<div className="form-group col-md-2">
<label htmlFor="date">Date</label>
<select className="form-control" name="date" id="date" onChange={this.handleChange} value={this.state.date}>
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
</select>
</div>
</div>
<div className="form-row">
<div className="form-group col-md-12">
<input id='formButton' className='btn btn-primary' type='submit' placeholder='Send' />
</div>
</div>
</form>
)
}
}
export { SearchForm }
The problem is input keywords doesn't change its value when I'm typing. What's wrong?
Make a common function for changing the state for input values.
handleInputChange(e) {
this.setState({
[e.target.name]: e.target.value
});
}
Make sure you mention name in every input tag. e.g:
<input name="someUniqueName" value={this.state.someState} onChange={this.handleInputChange} />
React Hooks makes this so much easier!!!
import React, {useState} from 'react'
function SearchForm () {
const [input, setInput] = useState("")
return (
<div className="SearchForm">
<input
value={input}
onChange={(e) => setInput(e.target.value)} />
</div>
)
}
It should be :
this.setState({
keywords: e.target.value
});
Your handleKeywordsChange function sets the state value whereas you are using this.state.keywords as value for input
handleKeywordsChange(e) {
console.log(1);
this.setState({
keywords: e.target.value
});
}
class InputKeywordCheck {
state = {
email: '',
}
handleInputChange (e) {
const {name, value } = e.target;
this.setState({[name]: value});
}
render() {
return (
<input name="email" value={this.state.email} onChange={this.handleInputChange} />
)
} }
I believe that you need to do something like this:
handleKeyWordsChange (e) {
this.setState({[e.target.name]: e.target.value});
}
I have some issue using asyncBlurFields in redux form, it just doesn't response,
container:
import React, { Component, PropTypes } from 'react'
import { connect } from 'react-redux'
import SupplierEditForm from '../../components/suppliers/SupplierEditForm'
import { reduxForm, change } from 'redux-form'
import { createSupplierRequest, updateSupplierRequest, fetchSupplierInfoRequest, validateSupplierRequest } from '../../api/suppliers'
import { resetSupplierForm, supplierFormSubmitSuccess } from '../../actions/SuppliersActions'
class SuppliersEditView extends Component {
constructor(props, context) {
super(props, context);
this.state = {isSubmitting: false}
}
componentWillMount() {
this.props.dispatch(resetSupplierForm())
}
componentDidMount() {
if(this.props.params.supplier_id) {
this.props.dispatch(fetchSupplierInfoRequest(this.props.params.supplier_id))
}
}
componentWillReceiveProps(nextProps) {
if(nextProps.supplier.isAction==true) {
if(!this.props.params.supplier_id) {
this.context.router.push('/suppliers/edit/'+nextProps.supplier.supplier_id)
} else {
this.props.dispatch(fetchSupplierInfoRequest(nextProps.supplier.supplier_id))
}
this.setState({isSubmitting:true})
setTimeout(() => {
this.hideStatus()
this.props.dispatch(supplierFormSubmitSuccess())
}, 1500)
}
}
hideStatus() {
this.setState({isSubmitting:false})
}
render() {
let pageHeader
if(this.props.fields.company_name.value) {
pageHeader = <h1 className="page-header">Suppliers - { this.props.fields.company_name.value }</h1>
}
else {
pageHeader = <h1 className="page-header">Suppliers</h1>
}
return (
<div className="container-fluid">
{pageHeader}
<SupplierEditForm
fields={this.props.fields}
handleSubmit={this.props.handleSubmit}
dispatchSupplier={this.props.dispatchSupplier.bind(this)}
supplier={this.props.supplier.payload}
isSubmitting={this.state.isSubmitting}
dispatchFieldChange={this.props.dispatchFieldChange}
supplier_id={this.props.params.supplier_id}
/>
</div>
)
}
}
const validateSupplier = (values, dispatch) => {
console.log('hi')
return new Promise((resolve, reject) => {
dispatch(validateSupplierRequest(values))
.then((response) => {
console.log(response)
});
})
}
const mapStateToProps = (state) => ({
supplier: state.suppliers.supplierInfo,
initialValues: state.suppliers.supplierInfo.payload
})
const mapDispatchToProps = (dispatch, props) => ({
dispatchSupplier: (values) => {
!props.params.supplier_id ? dispatch(createSupplierRequest(values)) : dispatch(updateSupplierRequest(values, props.params.supplier_id))
},
dispatchFieldChange: (field, value) => {
dispatch(change('SupplierEditForm',field,value))
}
})
SuppliersEditView.propTypes = {
asyncValidating: PropTypes.string.isRequired,
fields: PropTypes.object.isRequired,
resetForm: PropTypes.func.isRequired,
handleSubmit: PropTypes.func.isRequired,
submitting: PropTypes.bool.isRequired
}
SuppliersEditView.contextTypes = {
router: PropTypes.object
}
SuppliersEditView = reduxForm({
form: 'SupplierEditForm',
fields: ['company_logo','company_name', 'business_registration_no', 'mailing_address', 'billing_address', 'phone', 'email', 'fax', 'contact_person', 'contact_phone', 'contact_email', 'comments'],
asyncValidate: validateSupplier,
asyncBlurFields:['business_registration_no']
})(SuppliersEditView)
export default connect(mapStateToProps, mapDispatchToProps)(SuppliersEditView)
component:
import React, { Component } from 'react'
import { Link } from 'react-router'
import ReactDOM, { findDOMNode } from 'react-dom';
import { config } from '../../config'
import _ from 'lodash'
class SupplierEditForm extends Component {
constructor(props, context) {
super(props, context)
this.state = {
file: null,
imagePreviewUrl: null
}
}
handleImageChange(e) {
e.preventDefault();
let reader = new FileReader();
let file = e.target.files[0];
reader.onloadend = () => {
this.setState({
file: file,
imagePreviewUrl: reader.result
})
}
this.props.dispatchFieldChange(['company_logo'],file)
reader.readAsDataURL(file)
}
triggerImageUpload() {
ReactDOM.findDOMNode(this.refs.upload).click()
}
render () {
const { fields: { company_logo, company_name, business_registration_no, mailing_address, billing_address, phone, email, fax, contact_person, contact_phone, contact_email, comments }, handleSubmit, isSubmitting } = this.props
let imageSection
if(this.state.imagePreviewUrl) {
imageSection = <img src={this.state.imagePreviewUrl} width="100" onClick={this.triggerImageUpload.bind(this)}/>
} else if (_.isEmpty(this.props.supplier) || _.isNull(this.props.supplier.filename)){
imageSection = <div className="img-placeholder" onClick={this.triggerImageUpload.bind(this)}></div>
} else if (!_.isNull(this.props.supplier.filename) || !_.isEmpty(this.props.supplier)){
imageSection = <img src={config.FILE_DIR + this.props.supplier.filename} width="100" onClick={this.triggerImageUpload.bind(this)}/>
}
return (
<form onSubmit={handleSubmit(this.props.dispatchSupplier)} >
<button type="submit" disabled={isSubmitting} className="btn btn-primary mr8">
{
isSubmitting == true ?
<i className="fa fa-circle-o-notch fa-spin fa-fw"></i>
:
'Save'
}
</button>
<Link to="/suppliers" className="btn btn-secondary">Back</Link>
<div className="row">
{
isSubmitting ?
<div className="form-overlay"/>
: null
}
<div className="col-md-6">
<h2 className="mb24">Supplier details</h2>
<div className="form-group">
<label>Company logo</label>
<div className="col-md-12">
{imageSection}
</div>
<input type="file" ref="upload" className="col-xs-12 mb24 hide" {...company_logo} value={null} onChange={this.handleImageChange.bind(this)} />
</div>
<div className="form-group">
<label>Company name</label>
<input type="text" className="col-xs-12" {...company_name} required/>
</div>
<div className="form-group">
<label>Business registration no.</label>
<input type="text" className="col-xs-12" {...business_registration_no} required/>
</div>
<div className="form-group">
<label>Mailing address</label>
<input type="text" className="col-xs-12" {...mailing_address} required/>
</div>
<div className="form-group">
<label>Billing address</label>
<input type="text" className="col-xs-12" {...billing_address} required/>
</div>
<div className="form-group">
<label>Comments</label>
<textarea type="text" className="col-xs-12" {...comments} required></textarea>
</div>
</div>
<div className="col-md-6">
<h2 className="mb24">Contact details</h2>
<div className="form-group">
<label>Phone</label>
<input type="text" className="col-xs-12" {...phone} required/>
</div>
<div className="form-group">
<label>Fax</label>
<input type="text" className="col-xs-12" {...fax} required/>
</div>
<div className="form-group">
<label>Email</label>
<input type="email" className="col-xs-12" {...email} required/>
</div>
<div className="form-group">
<label>Contact person</label>
<input type="text" className="col-xs-12" {...contact_person} required/>
</div>
<div className="form-group">
<label>Contact phone</label>
<input type="text" className="col-xs-12" {...contact_phone} required/>
</div>
<div className="form-group">
<label>Contact email</label>
<input type="email" className="col-xs-12" {...contact_email} required/>
</div>
</div>
</div>
</form>
)
}
}
export default SupplierEditForm
However, whenever form is submitted, business_registration_no is suppose to respond on input lost focus, but it does not respond, have been trying for whole day. The weird thing is instead of firing this.props.dispatchSupplier when handleSubmit is invoked, it fires asyncValidate. Is there anything wrong in my code? Desperate for help!!
yep. need to use the Field-component and then also pass onBlur to that component..
like so :
https://github.com/erikras/redux-form/issues/1834
or so:
render() {
const { input: { value, onChange, onBlur }, meta: { touched, error } } = this.props
return (
<div>
<div className="example-class">
<input
type="tel"
className={this.inputFormClass(touched, error)}
autoComplete="on"
onChange={this.setPhoneNumber.bind(this)}
placeholder="some Placeholder"
onBlur={() => onBlur(value)}
/>
</div>
{this.showErrorMessage(touched, error)}
</div>
)
}