React Router Dropdown Вызов другого компонента, передающего идентификаторы параметров через URL - PullRequest
0 голосов
/ 19 января 2020

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

Это моя модель. Bill:

 const mongoose = require('mongoose');
 const { Schema } = mongoose;

 const billSchema = new Schema({

     number: Number,

     date: {type: Date, default: Date.now()},

     type: String,

     locale: String,

  client: {
      type: mongoose.Schema.Types.ObjectId,
      ref: 'clients'
    },
  provider: {
     type: mongoose.Schema.Types.ObjectId,
     ref: 'providers'
   },
  detail: [{
         quantity: Number,

          product: {

                    code: Number,
                    name: String,
                    price: Number
          },
           undertotal: Number
       }],
           total: Number
         }
    );
    mongoose.model('bills', billSchema);

мой почтовый маршрут in billsController:

  app.post("/api/bills/client/:clientId/provider/:providerId", async (req, res) => {

      const {
          name,
          type,
          locale,
          detail,
          total
         } = req.body;

      const clientId = req.params.clientId;

      const providerId = req.params.providerId;

       let existingClient = await Client.findById(clientId);

            if (!existingClient) {
                return res.status(404).json({
                message: "client not found"
              });
               }
       let existingProvider = await Provider.findById(providerId);

           if(!existingProvider){
                return res.status(404).json({
                message: "provider not found"
              });
              } 
   const bill = new Bill({
        name,
        date: new Date(),
        type,
        locale,
        client: existingClient._id,
        provider: existingProvider._id,
        detail,
        total
        });
     try {
         let newBill = await bill.save();
         res.status(201).send(newBill);
        } catch (err) {
         if (err.name === "MongoError") {
            res.status(409).send(err.message);
           }
         console.log(err);
        res.status(500).send(err);
       }
      }); 

И, наконец, внешний интерфейс, в котором я, BillForm и NewBillWithRelationShips:

BillForm.jsx

  const ClientAndProvider = (params) =>{
     return (<div><Redirect to= 
  {`/bills/newBill/client/${params.clientId}/proveedor/${params.providerId}`} /></div>)
  }

      componentDidMount(){

      this.props.bookClientsToMakeBill();
      this.props.bookProvidersToMakeBill();
        }

   componentWillReceiveProps = nextProps => {
      // Load Contact Asynchronously
       const { bill } = nextProps;
       if (bill._id !== this.props.bill._id) {
        // Initialize form only once
        this.props.initialize(bill);
        this.isUpdating = true;
           }
       };

    constructor(props){
     super(props);
      this.state = {
       client: '',
       provider: ''
       };
         }

    onChange = (e) =>{
      this.setState({
        client: e.target.value,
        provider: e.target.value
      })
     }

  render(){

      const { selectedClient,selectedProvider,handleSubmit, loading, submitting, pristine, 
            reset } = this.props;

      if (loading) {
         return <span>Loading...</span>;
        }

    return (
          <form onSubmit={handleSubmit}>

    <div className="col-md-4 mb-3">
            <label >Client:</label>
            <select className="custom-select d-block w-100" name="bill.client" value= 
                    {this.state.selectedClient} onChange={this.onChange.bind(this)}>

                   { this.props.clientsList.map(selectedClient => {

                 return(
                         <option  key={selectedClient._id}  value={selectedClient._id}> 
                      {selectedClient.name}</option>
                        )
                          })}
             </select>
              </div>

                      <div className="col-md-4 mb-3">
                    <label >Provider:</label>
                   <select className="custom-select d-block w-100" name="bill.provider" value= 
          {this.state.selectedProvider} onChange={this.onChange.bind(this)}>

           { this.props.providersList.map(selectedProvider => {

                  return(
                          <option  key={selectedProvider._id}  value= 
  {selectedProvider._id}>{selectedProvider.name}</option>
                        )
                          })}
             </select>
              </div>

            {<Route path="/bills/newBill/client/:clientId/provider/:providerId" exact 
         strict render={({match}) =>
               (
             this.state.selectedClient && this.state.selectedProvider ? (<ClientAndProvider 
   clientId={match.params.clientId} providerId={match.params.providerId}/>)

              : (<Redirect to="/bills/new" />)
     )}/>}

         <Link className='btn btn-light mr-2' to='/bills'>
                Cancel
               </Link>
               <button className='btn btn-primary mr-2' type='submit'>
                 {this.isUpdating ? 'Update' : 'Create'}
               </button>
            </form>
       );
    }
   }
 function mapState(state){
    return {
        clientsList: state.clientsDs.clientsList,
        providersList: state.providersDs.providersList
    }
  }
  const actions = {

    bookClientsForMakeBill,
    bookProvidersForMakeBill   
        };

  const selector = formValueSelector('bill')

  BillForm = connect(

     state =>{

        const selectedClient = selector(state,'client')

         const selectedProvider = selector(state,'provider')

               return{
            selectedClient: `${selectedClient}`,
            selectedProvider: `${selectedProvider}`
         }
  }
   )(BillForm);

  BillForm = connect(mapState,actions)(BillForm);

  export default reduxForm({ form: 'bill', validate: validations })(BillForm);

И наконец, NewBillWithRelationShips:

NewBillWithRelationShips.jsx

   state = {
      redirect: false
    };

   componentDidMount() {
      this.props.newBill();

      let {clientId} = this.props.match.params;

       this.clientId = clientId;

             let{providerId} = this.props.match.params;

             this.providerId = providerId;
     }

    submit = bill => {
        return this.props
        .saveBillWithRelationships(bill,this.clientId,this.providerId)
        .then(response => this.setState({ redirect: true }))
        .catch(err => {
           throw new SubmissionError(this.props.errors);
         });
     };

     render() {
       return (
         <div>
          <h2>New Bill</h2>
         {this.state.redirect ? (
            <Redirect to='/bills' />
            ) : (
             <BillForm bill={this.props.bill} clientId = {this.props.clientId} 
        providerId = {this.props.providerId} onSubmit={this.submit} />
          )}
        </div>
      );
      }
    }

  function mapStateToProps(state) {
    return {
       bill: state.billsDs.bill,
       errors: state.billsDs.errors
    };
    }

   export default connect(
     mapStateToProps,
      { newBill, saveBillWithRelationships }
    )(NewBillWithRelationShips);

Как видите, ожидаемый результат в URL-адресе следующий: например, /bills/newBill/client/418rujrn23/provider/2344junnnhj

Но реальный результат: /bills/newBill/client/undefined/provider/undefined

Я не передаю значения идентификаторов клиентов и провайдеров из раскрывающихся списков (см. Тег select)

Что не так?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...