mongodb 如何使用axios将mongoose objectId从后端发布到前端react-select

fjnneemd  于 2022-11-28  发布在  Go
关注(0)|答案(2)|浏览(138)

我有一个简单的后端代码,它可以很好地与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”
我想检索客户详细信息数据到前端选择部分,选择一个选项,并能够提交所有数据。谢谢

guicsvcw

guicsvcw1#

您在前端和后端都有一些问题。
尝试按如下方式更改组件:

class Billing extends Component {
  constructor() {
    super();
    this.state = {
      clients: [],
      clientdetails: '',
      paymentReferenceCode: '',
      paymentType: '',
      paymentDescription: '',
      procedureAmount: '',
      paymentDiscount: '',
      AmountPaid: '',
      Total: '',
    };
    this.handleSubmit = this.handleSubmit.bind(this);
    this.handleChange = this.handleChange.bind(this);
    this.handleChangeClientDetails = this.handleChangeClientDetails.bind(this);
  }

  componentDidMount() {
    this.loadData();
  }

  handleChange(event) {
    this.setState({
      ...this.state,
      [event.target.name]: event.target.value,
    });
  }

  handleChangeClientDetails(newValue) {
    this.setState({
      ...this.state,
      clientdetails: newValue._id
    })
  }

  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({
          ...this.state,
          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,
    };
    if (!this.state.clientdetails) {
      console.log('Select client');
      return;
    }
    axios.post(`http://localhost:4000/Bill/addbill/${this.state.clientdetails}`, entry).then((response) => {
      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.clients}
                filterOption={this.customFilter}
                isClearable={true}
                search={true}
                components={{ IndicatorSeparator: () => null }}
                placeholder={'Select Client'}
                getOptionLabel={(option) => `${option.fullName} ${option._id}`}
                onChange={this.handleChangeClientDetails} />
              ...
          </div>
        </div>
      </div>
    );
  }
}

export default Billing;

并将参数添加到POST路由:

router.post("/addbill/:id", ... );
yqhsw0fo

yqhsw0fo2#

在你的路由器上,你使用了req.params.id,但是它从来没有声明过,因为你的clientdetails使用了clientid,它将是null

router.post("/addbill",async(req,res)=>{
    try {
        console.log(req.params);        
        const clientid = await clients.findOne({ _id: req.params.id });

应该是

//                    /-- req.params.id
router.post("/addbill/:id",async(req,res)=>{
    try {
        console.log(req.params);        
        const clientid = await clients.findOne({ _id: req.params.id });

请记住,现在您的路由将需要/clientid作为结尾。

相关问题