我有一个简单的后端代码,它可以很好地与Rest API配合使用
更新代码
ClientSchema.js
const mongoose = require('mongoose');
var Schema = mongoose.Schema;
const customerSchema = new Schema({
paymentReferenceCode:{
type: String,
required: true
},
paymentType:{
type: String,
required: true
},
paymentDescription:{
type: String,
required: true
},
procedureAmount:{
type: String,
required: true
},
paymentDiscount:{
type: Number,
required: true
},
AmountPaid:{
type: Number,
required: true
},
Total:{
type: Number,
required: true
},
clientdetails: {
ref: 'Client',
type: mongoose.Schema.Types.ObjectId
},
}, { timestamps: true })
module.exports = mongoose.model('Customer',customerSchema);
Client.js
const mongoose = require('mongoose');
const ClientSchema = new mongoose.Schema({
fullName:{
type:String,
required: true
},
dateofBirth:{
type:Date,
required: true
},
gender:{
type:String,
required: true
},
nationality:{
type:String,
required: true
},
address:{
type:String,
required: true
},
date:{
type:Date,
default:Date.now
}
});
module.exports = mongoose.model('Client', ClientSchema)
Router.js
router.post("/addbill",async(req,res)=>{
try {
console.log(req.params);
const clientid = await clients.findOne({ _id: req.params.id });
await new Customer({
clientdetails:clientid,
paymentReferenceCode:req.body.paymentReferenceCode,
paymentType:req.body.paymentType,
paymentDescription:req.body.paymentDescription,
procedureAmount:req.body.procedureAmount,
paymentDiscount:req.body.paymentDiscount,
AmountPaid:req.body.AmountPaid,
Total:req.body.Total
}).save(async (err, data) => {
if (err) {
console.log('err:', err);
res.status(500).json({
message: 'Something went wrong, please try again later.'
});
} else {
res.status(200).json({
message: 'Bill Created',
data,
id: data._id
});
}
});
} catch (error) {
res.status(422).json(error);
}
})
router.get('/', async (req, res) => {
try{
const data = await clients.find();
res.json(data)
}
catch(error){
res.status(500).json({message: error.message})
}
})
前端
Billing.js
import React, {Component } from "react";
import "bootstrap/dist/css/bootstrap.min.css"
import axios from "axios"
import SimpleReactValidator from "simple-react-validator"
import TextField from '@mui/material/TextField';
import $ from 'jquery'
import Select,{components} from "react-select";
import Box from '@mui/material/Box';
import NativeSelect from "@mui/material/NativeSelect";
import Button from "@mui/material/Button";
class Billing extends Component {
constructor(){
super()
this.state = {
clientdetails :{},
paymentReferenceCode: "",
paymentType: "",
paymentDescription: "",
procedureAmount: "",
paymentDiscount: "",
AmountPaid: "",
Total: "",
}
this.changePaymentReferenceCode = this.changePaymentReferenceCode.bind(this)
this.changePaymentType = this.changePaymentType.bind(this)
this.changePaymentDescription = this.changePaymentDescription.bind(this)
this.changeProcedureAmount = this.changeProcedureAmount.bind(this)
this.changePaymentDiscount = this.changePaymentDiscount.bind(this)
this.changeAMountPaid = this.changeAMountPaid.bind(this)
this.changeTOtal = this.changeTOtal.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
this.handleChange = this.handleChange.bind(this)
}
changePaymentReferenceCode(event){
this.setState({
paymentReferenceCode:event.target.value
})
}
changeProcedureAmount(event){
this.setState({
procedureAmount:event.target.value
})
}
changePaymentType(event){
this.setState({
paymentType:event.target.value
})
}
changePaymentDescription(event){
this.setState({
paymentDescription:event.target.value
})
}
changePaymentAmount(event){
this.setState({
paymentAmount:event.target.value
})
}
changePaymentDiscount(event){
this.setState({
paymentDiscount:event.target.value
})
}
changeAMountPaid(event){
this.setState({
AmountPaid:event.target.value
})
}
changeTOtal(event){
this.setState({
Total:event.target.value
})
}
handleChange(event) {
this.setState({
[event.target.name]: event.target.value
})
}
componentDidMount(){
this.loadData();
}
loadData = () => {
axios.get('http://localhost:4000/clients', {
headers: {"Access-Control-Allow-Origin": true,
'Access-Control-Allow-Credentials' : true,
'Access-Control-Allow-Methods':'GET,PUT,POST,DELETE,PATCH,OPTIONS',
crossorigin : true,
},
responseType : 'json'
})
.then((result) => {
console.log(result.data);
this.setState({
clients : result.data,
})
})
.catch((error) => {
console.log(error);
})
}
customFilter = (option, searchText) => {
if(
option.data.fullName.toLowerCase().includes(searchText.toLowerCase())
)
return true;
return false;
}
handleSubmit(event){
event.preventDefault()
const entry = {
paymentReferenceCode: this.state.paymentReferenceCode,
paymentType: this.state.paymentType,
paymentDescription: this.state.paymentDescription,
procedureAmount: this.state.procedureAmount,
paymentDiscount: this.state.paymentDiscount,
AmountPaid: this.state.AmountPaid,
Total: this.state.Total,
}
axios.post('http://localhost:4000/Bill/addbill', entry)
.then(response => {
this.setState({clientdetails: response.data})
console.log(response.data)
})
this.setState({
clientdetails:{},paymentReferenceCode: "",paymentType: "",paymentDescription: "",procedureAmount: "",
paymentDiscount: "",AmountPaid: "",Total: "",
})}
render() {
const displayNone = { display: 'none' }
return (
<div>
<div className="container">
<div className="form-div">
<p className="text-capitalize">Billing</p>
<Box component="form" onSubmit={this.handleSubmit} noValidate sx={{ mt: 1}}>
<Select
closeMenuOnSelect={true}
hideSelectedOptions={true}
options={this.state.clientdetails}
filterOption = {this.customFilter}
isClearable={true}
search={true}
components={{IndicatorSeparator: () => null,}}
placeholder={'Select Client'}
getOptionLabel={option => `${option.fullName} ${option._id}`}
onchange={this.customFilter}
></Select>
<TextField
margin="normal"
fullWidth
id="paymentReferenceCode"
label="PaymentRefernceCode"
name="paymentReferenceCode"
autoComplete="off"
value={this.state.paymentReferenceCode}
onChange={this.handleChange}
autoFocus
/>
<NativeSelect
fullWidth
onChange={this.handleChange}
value={this.state.paymentType}
inputProps={{
name: 'paymentType',
id: 'paymentType',
}}
>
<option >PaymentType</option>
<option value="Cash">Cash</option>
<option value="PayPal">PayPal</option>
<option value="MasterCard">MasterCard</option>
</NativeSelect>
<TextField
margin="normal"
fullWidth
InputLabelProps={{style : {color : 'black'} }}
id="paymentDescription"
label="Payment Description"
name="paymentDescription"
autoComplete="paymentDescription"
onChange={this.handleChange}
value={this.state.paymentDescription}
autoFocus
/>
<TextField
margin="normal"
fullWidth
id="AmountPaid"
label="Amount Paid"
name="AmountPaid"
autoComplete="AmountPaid"
onChange={this.handleChange}
value={this.state.AmountPaid}
autoFocus
/><TextField
margin="normal"
fullWidth
id="paymentDiscount"
label="Payment Discount"
name="paymentDiscount"
autoComplete="paymentDiscount"
onChange={this.handleChange}
value={this.state.paymentDiscount}
autoFocus
/>
<TextField
margin="normal"
fullWidth
id="procedureAmount"
label="Procedure Amount"
name="procedureAmount"
autoComplete="procedureAmount"
onChange={this.handleChange}
value={this.state.procedureAmount}
autoFocus
/>
<TextField
margin="normal"
fullWidth
id="Total"
label="Total Bill"
name="Total"
autoComplete="Total"
onChange={this.handleChange}
value={this.state.Total}
autoFocus
/>
<div id='loginSuccess' className="alert alert-success" style={displayNone} role="alert">
<strong>Success! </strong>Client Bill Entered Successful.
</div>
<Button
type="submit"
fullWidth
sx={{ mt: 3, mb: 2}}
>
<span className='btn btn-warning btn-block form-control form-group'>Submit</span>
</Button>
</Box>
</div>
</div>
</div>
);
}
}
export default Billing;
我尝试使用axios.post并提交表单。但是,我无法将clientdetails数据检索到前端,特别是表单的选择部分,它返回空值。但其他条目将通过后端。这是我在控制台中获得的内容。数据:已付金额:100总计:100创建时间:“2022-11- 25 T22:31:57.306Z”客户详细信息:null付款说明:“住宿”付款折扣:100付款参考代码:“2345”付款类型:“现金”程序金额:“3”更新时间:“2022年11月25日22:31:57.306Z”__版本号:原型:目标编号:“6381425 db 019 f3 f9 a48047 ae”
我想检索客户详细信息数据到前端选择部分,选择一个选项,并能够提交所有数据。谢谢
2条答案
按热度按时间guicsvcw1#
您在前端和后端都有一些问题。
尝试按如下方式更改组件:
并将参数添加到POST路由:
yqhsw0fo2#
在你的路由器上,你使用了
req.params.id
,但是它从来没有声明过,因为你的clientdetails
使用了clientid
,它将是null
。应该是
请记住,现在您的路由将需要
/clientid
作为结尾。