Создание отношения (OnetToMany) между 2 объектами в реагировать - PullRequest
1 голос
/ 21 октября 2019

У меня есть база данных, созданная на MYSQL, в которой есть две таблицы (Patient, Caregiver), которые связаны с сопоставлением OneToMany при весенней загрузке. Я хочу создать объект Patient в реагирующем Js во внешнем интерфейсе (но мне нужно будет указать лицо, осуществляющее уход за ним в момент создания), а затем отправить его бэкэнду, моя единственная проблема заключается в том, что я не уверен, как создать соединение.

Я попытался создать опцию выбора для справки по уходу от пациента для выбора из списка попечителя. Но я не могу сделать это, получив сообщение об ошибке: ## TypeError: Невозможно получить свойство 'name' с неопределенной или нулевой ссылкой ##

Мои лица, осуществляющие уход, и пациенты в весенней загрузке

@Entity
@Table(name = "Patient", schema = "mydbps")
public class Patient {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "idPatient", unique = true, nullable = false)
    private int idPatient;

    @Column(name = "patientName")
    private String patientName;

    @Column(name = "patientSurname")
    private String patientSurname;

    @Column(name = "patientGender")
    private String patientGender;

    @Column(name = "patientBirthdate")
    private Date patientBirthdate;

    @Column(name = "patientAddress")
    private String patientAddress;

    @Column(name = "patientEmail")
    private String patientEmail;

    @Column(name = "patientPassword")
    private String patientPassword;

    @ManyToOne
    @JoinColumn(name = "Caregiver_idCaregiver")
    Caregiver Caregiver_idCaregiver;
}

@Entity
@Table(name="Caregiver",schema="mydbps")
public class Caregiver {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "idCaregiver", unique=true, nullable = false)
    private int idCaregiver;

    @Column(name="caregiverName")
    private String caregiverName;

    @Column(name="caregiverSurname")
    private String caregiverSurname;

    @Column(name="caregiverGender")
    private String caregiverGender;

    @Column(name="caregiverAddress")
    private String caregiverAddress;

    @Column(name="caregiverBirthdate")
    private String caregiverBirthdate;

    @Column(name="caregiverEmail")
    private String caregiverEmail;

    @Column(name="caregiverPassword")
    private String caregiverPassword;

    @JsonIgnore
    @OneToMany(mappedBy = "Caregiver_idCaregiver", cascade = CascadeType.ALL,fetch= FetchType.LAZY)
    private Set<Patient> patientList;}

Контроллеры:

@RestController
@CrossOrigin
@RequestMapping(value = "/caregivers")
public class CaregiverController {
    @Autowired
    private CaregiverService docService;

    @PostMapping
    public ApiResponse<Caregiver> saveUser(@RequestBody CaregiverDTO user){
        return new ApiResponse<>(HttpStatus.OK.value(), "Caregiver saved successfully.",docService.insert(user));
    }

    @GetMapping
    public ApiResponse<List<Caregiver>> listUser(){
        return new ApiResponse<>(HttpStatus.OK.value(), "Caregivers list fetched successfully.",docService.findAll());
    }

    @GetMapping("/{id}")
    public ApiResponse<Caregiver> getOne(@PathVariable int id){
        return new ApiResponse<>(HttpStatus.OK.value(), "Caregiver fetched successfully.",docService.findCaregiverByIdCaregiver(id));
    }

    @PutMapping("/{id}")
    public ApiResponse<CaregiverDTO> update(@RequestBody CaregiverDTO userDto) {
        return new ApiResponse<>(HttpStatus.OK.value(), "Caregiver updated successfully.",docService.update(userDto));
    }

    @DeleteMapping("/{id}")
    public ApiResponse<Void> deleteUser(@PathVariable int id) {
        docService.deleteUser(docService.findCaregiverByIdCaregiver(id));
        return new ApiResponse<>(HttpStatus.OK.value(), "Caregiver deleted successfully.", null);
    }


@RestController
@CrossOrigin
@RequestMapping(value = "/patients")
public class PatientController {


    @Autowired
    private PatientService docService;

    @PostMapping
    public ApiResponse<Patient> saveUser(@RequestBody PatientDTO user){
        return new ApiResponse<>(HttpStatus.OK.value(), "User saved successfully.",docService.insert(user));
    }

    @GetMapping
    public ApiResponse<List<Patient>> listUser(){
        return new ApiResponse<>(HttpStatus.OK.value(), "User list fetched successfully.",docService.findAll());
    }

    @GetMapping("/{id}")
    public ApiResponse<Patient> getOne(@PathVariable int id){
        return new ApiResponse<>(HttpStatus.OK.value(), "User fetched successfully.",docService.findPatientByIdPatient(id));
    }

    @PutMapping("/{id}")
    public ApiResponse<PatientDTO> update(@RequestBody PatientDTO userDto) {
        return new ApiResponse<>(HttpStatus.OK.value(), "User updated successfully.",docService.update(userDto));
    }

    @DeleteMapping("/{id}")
    public ApiResponse<Void> deleteUser(@PathVariable int id) {
        docService.deleteUser(docService.findPatientByIdPatient(id));
        return new ApiResponse<>(HttpStatus.OK.value(), "User deleted successfully.", null);
    }




}

Реактивный компонент add-пациента

import React, { Component } from 'react'
import PatientApiService from "../../service/PatientApiService";
import CaregiverApiService from "../../service/CaregiverApiService";
import Select from 'react-select';

class AddPatientComponent extends Component{

    constructor(props){
        super(props);
        this.state ={
            patientName: '',
            patientSurname: '',
            patientEmail: '',
            patientPassword: '',
            patientGender: '',
            patientAddress: '',
            Caregiver_idCaregiver: '',
            caregivers: [],
            message: null
        }
        this.saveUser = this.saveUser.bind(this);
    }

  componentDidMount() {
        this.reloadCaregiverList();

    }
  reloadCaregiverList() {
            PatientApiService.fetchCaregivers()
                .then((res) => {
                    this.setState({caregivers: res.data.result})
                });
        }

    saveUser = (e) => {
        e.preventDefault();
        let user = {patientName: this.state.patientName, patientSurname: this.state.patientSurname, patientEmail: this.state.patientEmail, patientPassword: this.state.patientPassword, patientGender: this.state.patientGender, patientAddress: this.state.patientAddress,Caregiver_idCaregiver :this.state.Caregiver_idCaregiver};
        PatientApiService.addUser(user)
            .then(res => {
                this.setState({message : 'Patient added successfully.'});
                this.props.history.push('/patients');
            });
    }

    onChange = (e) =>
        this.setState({ [e.target.name]: e.target.value });

    render() {
        return(
            <div>
            <div>
                <h2 className="text-center">Add User</h2>
                <form>
                <div className="form-group">
                    <label>Name:</label>
                    <input type="text" placeholder="patientName" name="patientName" className="form-control" value={this.state.patientName} onChange={this.onChange}/>
                </div>

                <div className="form-group">
                    <label>Surname:</label>
                    <input type="patientSurname" placeholder="patientSurname" name="patientSurname" className="form-control" value={this.state.patientSurname} onChange={this.onChange}/>
                </div>

                <div className="form-group">
                    <label>Email:</label>
                    <input placeholder="Email" name="patientEmail" className="form-control" value={this.state.patientEmail} onChange={this.onChange}/>
                </div>

                <div className="form-group">
                    <label>Password:</label>
                    <input placeholder="Password" name="patientPassword" className="form-control" value={this.state.patientPassword} onChange={this.onChange}/>
                </div>

                <div className="form-group">
                    <label>Gender:</label>
                    <input placeholder="Gender" name="patientGender" className="form-control" value={this.state.patientGender} onChange={this.onChange}/>
                </div>

                <div className="form-group">
                    <label>Address:</label>
                    <input placeholder="Address" name="patientAddress" className="form-control" value={this.state.patientAddress} onChange={this.onChange}/>
                </div>

             <div className="form-group">
                 <div className="row">
                   <div className="col-md-4"></div>
                   <div className="col-md-4">
                   <label>Caregiver:</label>
                    <Select options={ this.state.caregivers } name="Caregiver_idCaregiver"  value={this.state.Caregiver_idCaregiver} onChange={(e)=>this.setState({ Caregiver_idCaregiver:e.value})} />

                   </div>
                   <div className="col-md-4"></div>
                 </div>
               </div>

                <button className="btn btn-success" onClick={this.saveUser}>Save</button>
            </form>
    </div>
     <div>
                                <h2 className="text-center">Caregiver Details</h2>
                                <table className="table table-striped">
                                    <thead>
                                        <tr>
                                            <th className="hidden">Id</th>
                                            <th>FirstName</th>
                                            <th>LastName</th>
                                            <th>caregiverEmail</th>
                                            <th>caregiverGender</th>
                                            <th>caregiverAddress</th>
                                        </tr>
                                    </thead>
                                    <tbody>
                                        {
                                            this.state.caregivers.map(
                                        caregiver =>
                                                    <tr key={caregiver.idCaregiver}>
                                                        <td>{caregiver.caregiverName}</td>
                                                        <td>{caregiver.caregiverSurname}</td>
                                                        <td>{caregiver.caregiverEmail}</td>
                                                        <td>{caregiver.caregiverGender}</td>
                                                        <td>{caregiver.caregiverAddress}</td>
                                                    </tr>
                                            )
                                        }
                                    </tbody>
                                </table>

                            </div>
                            </div>
        );
    }
}

export default AddPatientComponent;

Служба ApiPatient:

import axios from 'axios';

const USER_API_BASE_URL = 'http://localhost:8080/patients';
const CAREGIVER_API_BASE_URL='http://localhost:8080/caregivers';
class PatientApiService {

    fetchUsers() {
        return axios.get(USER_API_BASE_URL);
    }

    fetchUserById(userId) {
        return axios.get(USER_API_BASE_URL + '/' + userId);
    }

    deleteUser(userId) {
        return axios.delete(USER_API_BASE_URL + '/' + userId);
    }

    addUser(user) {
        return axios.post(""+USER_API_BASE_URL, user);
    }

    editUser(user) {
        return axios.put(USER_API_BASE_URL + '/' + user.id, user);
    }
    fetchCaregivers()
    {return axios.get(CAREGIVER_API_BASE_URL);}

}

export default new PatientApiService();

Мой почтальон получает ответ службы дляfetchCaregivers:


    "status": 200,
    "message": "Caregivers list fetched successfully.",
    "result": [
        {
            "idCaregiver": 1,
            "caregiverName": "Marius",
            "caregiverSurname": "Ioan",
            "caregiverGender": null,
            "caregiverAddress": null,
            "caregiverBirthdate": null,
            "patientList": []
        }
    ]
}

Но он не будет отображаться в раскрывающемся списке.

Я хочу выбрать опекуна из выпадающего списка, но я не вижу, также ошибка, которая появляется во время выполнения:

×
TypeError: Unable to get property 'name' of undefined or null reference
onChange
D:/AN 4/react-js-example-master/src/component/patient/AddPatientComponent.jsx:46
  43 | }
  44 | 
  45 | onChange = (e) =>
> 46 |     this.setState({ [e.target.name]: e.target.value });
     | ^
  47 | 
  48 | render() {
  49 |     return(

Спасибо!

1 Ответ

0 голосов
/ 21 октября 2019

Сначала убедитесь, что ваши параметры React-Select являются массивом объектов и содержат, как минимум, значение и свойство label для каждого параметра, например так:

    [
        {value:'value1', label:'label1', otherProperty:'otherProperty1'},
        {value:'value2', label:'label2', otherProperty:'otherProperty2'}
    ]

Для этого (при условии, чтоPatientApiService.fetchCaregivers() возвращает массив лиц, осуществляющих уход). Создайте метод renderOptions:

renderOptions=(options)=>{
    return options.map(option=>{
        return {value: option.idCaregiver , label:option.caregiverName}
    })
}

Далее имейте в виду: «React-Select» не возвращает типичный объект события, такой как:

{target:{value:'value' , label:'label' , name:'name'}}

Вместо этого он возвращает все, что вы передали в качестве опции для реквизита опций, например:

{value:'value' , label:'label'}

Следовательно, доступ к e.target приведет к неопределенности, более того, если вы попытаетесь получить доступ к e.target. name вы получите сообщение об ошибке, так как не можете получить доступ к .name of undefined.

Кроме того, вы также не сможете напрямую извлечь имя поля (так как это не является свойством возвращаемого объектаact-select return) если вы не передадите его явно в параметрах, таких как:

{value:'value1', label:'label1' , name:'someFieldName' , otherProperty:'otherProperty'}

Если вы не хотите переходить на обычный тег выбора, вам потребуется:

  1. ИзменитьonChangeчтобы компонентact-select был в том же формате, что и другие события onChange
  2. Используйте метод renderOptions сверху
  3. Удалите значение prop в качестве дорожек реагирования-выбора, которые для вас

Обновленный выбор теперь должен быть:

<Select 
    name="Caregiver_idCaregiver"//not stricly necessary 
    options={ this.formatOptions(this.state.caregivers) } 
    onChange={(e)=>this.onChange({target:{...e , name:'Caregiver_idCaregiver'}})}
/>

ДОПОЛНИТЕЛЬНО

Ваш PatientApiService не имеет метода saveUser, который вы вызываетеваш AddPatientComponent метод saveUser, вам нужно изменить его, чтобы он соответствовал либо editUser, либо addUser методу, который вы определили в вашем PatientApiService

Например, чтобы добавить пользователя:

saveUser = (e) => {
    e.preventDefault();
    let user = {patientName: this.state.patientName, patientSurname: this.state.patientSurname, patientEmail: this.state.patientEmail, patientPassword: this.state.patientPassword, patientGender: this.state.patientGender, patientAddress: this.state.patientAddress,Caregiver_idCaregiver :this.state.Caregiver_idCaregiver};
    PatientApiService.addUser(user)
        .then(res => {
            this.setState({message : 'Patient added successfully.'});
            this.props.history.push('/patients');
        });
}

Упрощенный рабочий пример:

import React from 'react';
import ReactDOM from 'react-dom'
import Select from 'react-select';

class SomeComponent extends React.Component {
    state={
        caregivers:[ { idCaregiver: '1', caregiverName: 'User1', otherData:'data1'}, { idCaregiver: '2', caregiverName: 'User2', otherData:'data2' },],
        Caregiver_idCaregiver:''
    }

    saveUser = (e) => {
        e.preventDefault();

        const user = {Caregiver_idCaregiver : this.state.Caregiver_idCaregiver};
        const foundCaregiverObj = this.state.caregivers.find(caregiver=> caregiver.idCaregiver === this.state.Caregiver_idCaregiver)

        console.log(user)
        console.log(foundCaregiverObj)
    }

    onChange = (e) =>{
        this.setState({ [e.target.name]: e.target.value });
    }

    renderOptions=(options)=>{
        return options.map(option=>{
            return {value: option.idCaregiver , label:option.caregiverName}
        })
    }
    render(){
        return (
            <div>
                <label>Caregiver:</label>
                <Select options={ this.renderOptions(this.state.caregivers) } name="Caregiver_idCaregiver"  onChange={(e)=>this.onChange({target:{...e , name:'Caregiver_idCaregiver'}})}/>
                <button onClick={this.saveUser}>Save</button>
            </div>
        )
    }
}

ReactDOM.render(
    <SomeComponent />,
    document.getElementById("root")
);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...