core1024
@core1024

Как правильно сформировать Json с вложенным объектом при отправке формы redux-form?

Подскажите пожалуйста по такому вопросу:
есть следующая форма redux-form, для создания нового сотрудника:

import React from 'react';
import { connect } from 'react-redux';
import { Field, reduxForm, formValueSelector } from 'redux-form';
import {getEmployeesAction} from "../../../redux/actions/employeeActions";

class AssetForm extends React.Component {

    componentDidMount() {
        this.props.getEmployeesAction();
    }

    onSubmit = formValues => {
        this.props.onRenderPropSubmit(formValues);
    };

    render() {
        const {
            assetTypeValue,
            pristine,
            reset,
            submitting,
        } = this.props;

        return (
            <form onSubmit={this.props.handleSubmit(this.onSubmit)}>

                <div className="form-group">
                    <Field component={"select"} className="form-control" name="assetType" aria-describedby="assetTypeHelp">
                        <option />
                        <option value={"TYPE1"}>Тип 1</option>
                        <option value={"TYPE2"}>Тип 2</option>
                        <option value={"TYPE3"}>Тип 3</option>
                    </Field>
                    <small className="form-text text-muted" id="assetTypeHelp">Тип устройства</small>
                </div>
  
                <div className="form-group">
                    <Field component={"input"} className="form-control" type="text" name={"modelName"} aria-describedby="modelNameHelp" required />
                    <small className="form-text text-muted" id="modelNameHelp">Модель устройства</small>
                </div>

                <div className="form-group">
                    <Field component={"select"} className="form-control" name="employee" aria-describedby="employeeHelp">
                        <option />
                        {this.props.employees.map(employee => {
                            if (employee) {
                                return (
                                    <option key={employee.id} value={JSON.stringify(employee)}>{employee.fullName}</option>
                                );
                            }
                            else return null;
                        })}
                    </Field>
                    <small className="form-text text-muted" id="employeeHelp">Сотрудник</small>
                </div>

                }

                {assetTypeValue === "TYPE2" &&
                    <div>
                        <div className="form-group">
                            <Field component={"input"} className="form-control" type="text" name={"description"}
                                aria-describedby="descriptionHelp" required />
                            <small className="form-text text-muted" id="descriptionHelp">Описание</small>
                        </div>
                    </div>
                }

                <div>
                    <button type="submit" disabled={pristine || submitting}>
                        Submit
                    </button>
                    <button type="button" disabled={pristine || submitting} onClick={reset}>
                        Clear Values
                    </button>
                </div>
            </form>
        );
    }
}

const mapStateToProps = ({ employees }) => {
    return {
        employees: Object.values(employees)
    };
};

// Decorate with connect to read form values
const selector = formValueSelector('assetForm'); // <-- same as form name
AssetForm = connect(state => {
    const assetTypeValue = selector(state, 'assetType');
    return { assetTypeValue };
})(AssetForm);

export default connect(mapStateToProps, {getEmployeesAction})(reduxForm({form: 'assetForm'})(AssetForm));


Тут же есть поле employee (сотрудник), куда загружается одноименный объект, у которого есть несколько полей (id, fullName, phoneNumber..). При отправке формируется JSON такого вида:
{
	"assetType":"TYPE1",
	"modelName":"124500000",
	
	"employee": "{
		"fullName" : "user1", 
		"position":"samplePos",
		"phoneNumber": "samplePhone"
	}"	
}

Контроллер при таком запросе отдает ошибку 400. А 201 Created отдает только в том случае, если отправить ему запрос такого вида:
{
	"assetType":"TYPE1",
	"modelName":"124500000",
	
	"employee": {
		"fullName" : "user1", 
		"position":"samplePos",
		"phoneNumber": "samplePhone"
	}	
}

Подскажите как можно поправить эту форму, чтобы получить правильный JSON на выходе?
Заранее благодарен за ответ
  • Вопрос задан
  • 156 просмотров
Решения вопроса 1
@Che603000
c 2011 javascript
Проблема в значении options value={JSON.stringify(employee)} фактически у вас там содержится строка (String).

div className="form-group">
                    <Field component={"select"} className="form-control" name="employee" aria-describedby="employeeHelp">
                        <option />
                        {this.props.employees.map(employee => {
                            if (employee) {
                                return (
                                    <option key={employee.id} value={JSON.stringify(employee)}>{employee.fullName}</option>
                                );
                            }
                            else return null;
                        })}
                    </Field>
                    <small className="form-text text-muted" id="employeeHelp">Сотрудник</small>
                </div>


исходя из документации https://redux-form.com/8.2.2/docs/api/field.md/ Вы можете попробовать добавить свойство parser в options. Скорее всего это должно сработать
<option key={employee.id} value={JSON.stringify(employee)} parse={(val, name)=>JSON.parse(val)}>{employee.fullName}</option>


Тем не менее, это несколько не обычный способ использования select. Более логичным выглядит установка в options value={employee.id} и поиск фактического значения в this.props.employees.find(e=>e.id === employee) перед отправкой формы.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы