Reputation: 63687
I have validatioin in ReduxForm working until I have to validate a field whose name is nested ie: location.coordinates[0]
.
This data looks like such in the Redux Store:
"location" : {
"type" : "Point",
"coordinates" : [
103.8303,
4.2494
]
},
When trying to validate such fields using
Approach 1
if (!values.location.coordinates[0]) {
errors.location.coordinates[0] = 'Please enter a longtitude';
}
I am getting error:
TypeError: Cannot read property 'coordinates' of undefined
Approach 2
if (values.location !== undefined) {
errors.location.coordinates[0] = 'Please enter a longtitude';
errors.location.coordinates[1] = 'Please enter a latitude';
}
I am getting error:
TypeError: Cannot read property 'coordinates' of undefined
Question: What is the proper way to handle such fields?
/src/containers/Animals/AnimalForm.js
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { reduxForm, Field } from 'redux-form';
import { renderTextField } from './FormHelpers';
class AnimalForm extends Component {
render() {
return (
<div>
<form onSubmit={ this.props.handleSubmit }
<Field
label="Longitude"
name="location.coordinates[0]"
component={renderTextField}
type="text"
/>
<Field
label="Latitude"
name="location.coordinates[1]"
component={renderTextField}
type="text"
/>
</form>
</div>
)
}
}
const validate = values => {
let errors = {}
if (values.location !== undefined) {
errors.location.coordinates[0] = 'Please enter a longtitude';
errors.location.coordinates[1] = 'Please enter a latitude';
}
if ((values.location !== undefined) && (values.location.coordinates !== undefined)) {
errors.location.coordinates[0] = 'Please enter a longtitude';
errors.location.coordinates[1] = 'Please enter a latitude';
}
return errors;
}
function mapStateToProps(state) {
return { ... }
}
export default connect(mapStateToProps)(reduxForm({
form: 'animal',
validate
})(AnimalForm))
/src/containers/Animals/FormHelper.js
import React from 'react';
import { FormGroup, Label, Input, Alert } from 'reactstrap';
export const renderTextField = ({input, type, meta: {touched, error}, ...custom}) => (
<div>
<Label>{ label }</Label>
<Input
type={type}
value={input.value}
onChange={input.onChange}
/>
{touched && error && <Alert color="warning">{ error }</Alert>}
</div>
)
Upvotes: 2
Views: 1405
Reputation: 34014
The below solution would work
const validate = values => {
let errors = values;
if(values){
if (values.location) {
errors.location.coordinates[0] = 'Please enter a longtitude';
errors.location.coordinates[1] = 'Please enter a latitude';
}
}
return errors;
}
Upvotes: 0
Reputation: 181
In the validate method, how about structuring the initial errors object as such:
let errors = {
location: {
coordinates: []
}
}
Upvotes: 2