skip to Main Content

I have a simple backend code which works well with Rest API

updated code

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})
    }
})

Frontend

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;

I tried to use axios.post and submit the form. However, am not able to retrieve clientdetails data to the frontend in particular the select part of the form, it returns null. But the other entries go through to the backend. This is what am getting in the console.
data:
AmountPaid: 100
Total: 100
createdAt: "2022-11-25T22:31:57.306Z"
clientdetails: null
paymentDescription: "accomodation"
paymentDiscount: 100
paymentReferenceCode: "2345"
paymentType: "Cash"
procedureAmount: "3"
updatedAt: "2022-11-25T22:31:57.306Z"
__v: 0
_id: "6381425db019f3f9a48047ae"
[[Prototype]]: Objectid: "6381425db019f3f9a48047ae"

I would like to retrieve the clientdetails data to the frontend select section, select an option and be able to submit all the data.Thank you

2

Answers


  1. At your router you’re using req.params.id but it’s never declared, since your clientdetails uses the clientid, it’ll be null. Easy to fix.

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

    should be

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

    just remember that now your route will need the /clientid at the end.

    Login or Signup to reply.
  2. You have a few problems, both on front-end and back-end.
    Try to change your component like this:

    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;
    

    And add the parameter to the POST route:

    router.post("/addbill/:id", ... );
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search