Imran Abdalla
Imran Abdalla

Reputation: 115

Sending Requests from react-redux to backend API

My back-end server is NodeJs connect to MongoDB atlas, there's a route called companyorders which accepts post requests to enable users to create company orders. I'm trying to send the post request from react application through Redux.

Here's my code...

Redux Store

import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers';

const initialState = {};

const middleware = [thunk];

const store = createStore(
  rootReducer,
  initialState,
  compose(
    applyMiddleware(...middleware),
    window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
  )
);

export default store;

Redux Actions

import axios from 'axios';
import { GET_ERRORS, ADD_COMPANY_ORDER } from './types';

// Add Company Order
export const addCompanyOrder = (orderData) => (dispatch) => {
  axios
    .post('/api/companyorder/create', orderData)
    .then((res) =>
      dispatch({
        type: ADD_COMPANY_ORDER,
        payload: res.data,
      })
    )
    .catch((err) =>
      dispatch({
        type: GET_ERRORS,
        payload: err.response.data,
      })
    );
};

Redux Reducers

import { ADD_COMPANY_ORDER } from '../actions/types';

const initialState = {};

export default function addCompanyOrder(state = initialState, action) {
  switch (action.type) {
    case ADD_COMPANY_ORDER:
      return {
        ...state,
        initialState: action.payload,
      };
    default:
      return state;
  }
}

Redux Combined Reducers

import { combineReducers } from 'redux';
import addCompanyOrder from './companyOrderReducer';

export default combineReducers({
  co_order: addCompanyOrder,
});

The react component

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import { Link } from 'react-router-dom';
import PropTypes from 'prop-types';
import { addCompanyOrder } from '../../actions/companyOrderActions';
class Companyorder extends Component {
  constructor(props) {
    super(props);
    this.state = {
      orderName: '',
      date: '',
      orderQuantity: '',
      orderSupplier: '',
      orderCost: '',
      oderTax: '',
      supplierInfo: [
        {
          name: '',
          location: '',
          phone: '',
          email: '',
        },
      ],
      oderReceived: '',
      errors: {},
    };
    this.onChange = this.onChange.bind(this);
    this.onSubmit = this.onSubmit.bind(this);
  }
  componentDidUpdate(nextProps) {
    if (nextProps.errors) {
      this.setState({ errors: nextProps.errors });
    }
  }
  onSubmit(e) {
    e.preventDefault();

    const newOrder = {
      orderName: this.state.orderName,
      date: this.state.date,
      orderQuantity: this.state.orderQuantity,
      orderSupplier: this.state.orderSupplier,
      orderCost: this.state.orderCost,
      oderTax: this.state.oderTax,
      name: this.state.name,
      location: this.state.location,
      phone: this.state.phone,
      email: this.state.email,
    };

    this.props.addCompanyOrder(newOrder);
  }

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

  render() {
    const { errors } = this.state;
    return (
      <div className="container">
        <div className="row">
          <div className="col-md-6">
            <Link to="/" className="btn btn-link">
              <i className="fas fa-arrow-circle-left" /> Back To Dashboard
            </Link>
          </div>
        </div>

        <div className="card">
          <div className="card-header"> Company Order Form</div>
          <div className="card-body">
            <div className="form-group row">
              <label htmlFor="orderName" className="col-2 col-form-label">
                Order Name
              </label>
              <div className="col-10">
                <input
                  className="form-control"
                  type="text"
                  name="orderName"
                  minLength="2"
                  required
                  onChange={this.onChange}
                  value={this.state.orderName}
                  error={errors.orderName}
                />
              </div>
            </div>

            <div className="form-group row">
              <label htmlFor="date" className="col-2 col-form-label">
                Order Date
              </label>
              <div className="col-10">
                <input
                  className="form-control"
                  type="date"
                  name="date"
                  minLength="2"
                  required
                  onChange={this.onChange}
                  value={this.state.date}
                  error={errors.date}
                />
              </div>
            </div>

            <div className="form-group row">
              <label htmlFor="orderQuantity" className="col-2 col-form-label">
                Order Quantity
              </label>
              <div className="col-10">
                <input
                  className="form-control"
                  type="number"
                  name="orderQuantity"
                  minLength="2"
                  required
                  onChange={this.onChange}
                  value={this.state.orderQuantity}
                  error={errors.orderQuantity}
                />
              </div>
            </div>

            <div className="form-group row">
              <label htmlFor="orderSupplier" className="col-2 col-form-label">
                Order Supplier
              </label>
              <div className="col-10">
                <input
                  className="form-control"
                  type="text"
                  name="orderSupplier"
                  minLength="2"
                  required
                  onChange={this.onChange}
                  value={this.state.orderSupplier}
                  error={errors.orderSupplier}
                />
              </div>
            </div>

            <div className="form-group row">
              <label htmlFor="orderCost" className="col-2 col-form-label">
                Order Cost
              </label>
              <div className="col-10">
                <input
                  className="form-control"
                  type="text"
                  name="orderCost"
                  minLength="2"
                  required
                  onChange={this.onChange}
                  value={this.state.orderCost}
                  error={errors.orderCost}
                />
              </div>
            </div>

            <div className="form-group row">
              <label htmlFor="oderTax" className="col-2 col-form-label">
                Order Tax
              </label>
              <div className="col-10">
                <input
                  className="form-control"
                  type="text"
                  name="oderTax"
                  minLength="2"
                  required
                  onChange={this.onChange}
                  value={this.state.oderTax}
                  error={errors.orderTax}
                />
              </div>
            </div>
            <div className="card-header">
              <h5>Supplier info</h5>
              <div className="card-body">
                <div className="form-group row">
                  <label htmlFor="name" className="col-2 col-form-label">
                    Name
                  </label>
                  <div className="col-10">
                    <input
                      className="form-control"
                      type="text"
                      name="name"
                      minLength="2"
                      required
                      onChange={this.onChange}
                      value={this.state.name}
                      error={errors.name}
                    />
                  </div>
                </div>
                <div className="form-group row">
                  <label htmlFor="location" className="col-2 col-form-label">
                    Location
                  </label>
                  <div className="col-10">
                    <input
                      className="form-control"
                      type="text"
                      name="location"
                      minLength="2"
                      required
                      onChange={this.onChange}
                      value={this.state.location}
                      error={errors.loaction}
                    />
                  </div>
                </div>
                <div className="form-group row">
                  <label htmlFor="phone" className="col-2 col-form-label">
                    Phone
                  </label>
                  <div className="col-10">
                    <input
                      className="form-control"
                      type="text"
                      name="phone"
                      minLength="2"
                      required
                      onChange={this.onChange}
                      value={this.state.phone}
                      error={errors.phone}
                    />
                  </div>
                </div>
                <div className="form-group row">
                  <label htmlFor="email" className="col-2 col-form-label">
                    Email
                  </label>
                  <div className="col-10">
                    <input
                      className="form-control"
                      type="text"
                      name="email"
                      minLength="2"
                      required
                      onChange={this.onChange}
                      value={this.state.email}
                      error={errors.email}
                    />
                  </div>
                </div>
              </div>
            </div>
            <input
              type="submit"
              value="Submit"
              className="btn btn-primary btn-block"
            />
          </div>
        </div>
      </div>
    );
  }
}

Companyorder.propTypes = {
  addCompanyOrder: PropTypes.func.isRequired,
  co_order: PropTypes.object.isRequired,
  errors: PropTypes.object.isRequired,
};

const mapStateToProps = (state) => ({
  co_order: state.co_order,
  errors: state.errors,
});

export default connect(mapStateToProps, { addCompanyOrder })(
  withRouter(Companyorder)
);

The code is compiling successfully, but redux is not making any request, even not filling the redux state. If know the error or a better way to do it, please leave your reply and I'm very appreciated.

Upvotes: 1

Views: 1282

Answers (1)

dglozano
dglozano

Reputation: 6607

It seems like you are not calling your onSubmit handler anywhere in your code. You should probably wrap your form with a form tag and set the onSubmit prop to your handler function.

<form onSubmit={this.onSubmit}>
...
</form>

By the way, it doesn't seem like your reducer is correct. It seems to me that you probably want something more similar to this:

import { ADD_COMPANY_ORDER } from '../actions/types';

const initialState = {
 co_orders: []
};

export default function addCompanyOrder(state = initialState, action) {
  switch (action.type) {
    case ADD_COMPANY_ORDER:
      const newCoOrder = action.payload;

      return {
        co_orders: [...state.co_orders, newCoOrder];
      };
    default:
      return state;
  }
}

Other unrelated tips if your app increases in complexity:

Upvotes: 1

Related Questions