I'm using redux-form and I want getting values were inserted by user when I'm editing the form. With the other input I haven't got any problem, only with dropdown (select component).
I'm using a class component called ServiceForm, which has inside a functional component called renderTodos. The dropdown "relatedTodos" gets me all todos from api rest.
This is my class component:
componentWillReceiveProps = nextProps => {
// Load Contact Asynchronously
const { service } = nextProps;
if (service._id !== this.props.service._id) {
// Initialize form only once
this.props.initialize(service);
this.isUpdating = true;
}
};
componentDidMount(){
this.props.searchTodos();
}
constructor(props){
super(props);
this.state = {
//LOOK THE FOLLOWING LINE PLEASE
todo: props.todo.name};
};
onChange = (e) =>{
this.setState({
todo: e.target.value
})
}
renderArrayTodos = ({fields, meta: { error,submitFailed}},input) => (
<dl>
<dt>
<button type="button" className='btn btn-primary' style=
{{fontWeight:'bold',color:'black'}} onClick={() =>
fields.push()}>Add todo</button>
{submitFailed && error && <span>{error}</span>}
</dt>
{ fields.map((relatedTodo, index) =>
<dd key={index}>
<br></br>
<button className='btn btn-primary' style={{fontWeight:'bold',color:'black'}}
type="button"
title="Remove Todo"
onClick={() => { fields && fields.remove(index)
}}> Remove </button>
<h4><b>Todo's widget number {index + 1}</b></h4>
<div className="row" style={
{textAlign: 'center',
justifyContent: 'center',
paddingRight: 20,
margin: '10 10px 10 10px'
}}>
<label style={{fontStyle:
'arial',fontWeight:'bold',fontSize:17}}>Todo:</label>
<Field
className="custom-select d-block w-100" name={`${relatedTodo}`}
value={this.state.todo} onChange={this.onChange.bind(this)}
component="select" placeholder={!input.value ? 'Please, insert a todo' : input.value}>
{/* <option value="" hidden style={{fontStyle:
'arial',fontWeight:'bold'}}>Please, select a todo</option> */}
{/*PLACEHOLDER FOR TODO SELECT IN SERVICE FORM: Please, select a todo
when I'm CREATING a service,ON THE CONTRARY when I'm EDITING a service,
the placeholder will be the reflected todo value I inserted when I
created the service. e.g. I inserted todo 5, when I'm EDITING the
created service, only todo I inserted should be showed like todo 5. */}
<option value={input.value} hidden style={{fontStyle:
'arial',fontWeight:'bold'}}>{!input.value ? 'Please, select a todo'
: input.value}</option>
{ this.props.todoList.map(todo => {
return(
<option key={todo._id} value={todo._id} style={{fontStyle:
'arial',fontWeight:'bold'}} >{todo.name}</option>
)
})}
</Field>
</div>
</dd>
)
}
{error && <dt className="error">{error}</dt>}
</dl>
);
Here I connect action called "searchTodos and todoList (reducer)" with api:
const actions = {
searchTodos
};
function mapState(state){
return {
todoList: state.todosSoftware.todoList
}
}
ServiceForm= connect(mapState,actions)(ServiceForm);
The dropdown called "relatedTodos" and these are the todos in the following order: "todo 1, todo 2, todo 3, todo 4, todo 5".
When I'm creating a service
e.g.
I'm assing to my service, I'm clicking on button "add todo". Add a field called ${relatedTodo}
. I select
e.g.
todo 5.
When I'm editing the created service with only one assigned todo, Dropdown's placeholder should say "todo 5" not "please, select a todo" or the first element of the dropdown, which is "todo 1".
On the othen hand, when I'm editing the service, I've got this error: "cannot read name of undefined". This error is in the following code line.
constructor(props){
super(props);
this.state = {
//IN THE FOLLOWING LINE IS THE ERROR
todo: props.name.todo
}
}
When editing the service in the service form, the values of the select are reflected those entered by the user.