Home > front end >  How to post more than one object using React JS, Axios with a Spring boot backend?
How to post more than one object using React JS, Axios with a Spring boot backend?

Time:03-25

The API works when tested with Postman, however, I do not know how to send more than one post request from the front end of React JS. I have to send the image file to be uploaded along with the int variable 'root'.

Postman- Post Request:- Postman- Post Request

This is the API on SpringBoot

@PostMapping("/cost_image_upload")
    public status uploadFile(@RequestParam("file") MultipartFile file, @RequestParam("root") String root) throws IOException {
        List<cost> costs = costRepository.findAll();
        for(cost cost: costs) {
            if(cost.getRoot().equals(root)) {
                byte[] temp = file.getBytes();
                cost.setImage(temp);
                this.costRepository.save(cost);
                System.out.println("worked"   cost);
                return status.SUCCESS;
            }
        }
        System.out.println("didn't work");
        return status.FAILURE;
    }

This is CostService.js

import axios from 'axios';

const user_base_url = "http://localhost:8080/api";

class CostService{

    addCost(cost) {
        return axios.post(user_base_url   '/cost', cost);
    }

    uploadFile(image, root) {
        return axios.post(user_base_url   '/cost_image_upload', image, root);
    }

    showCost() {
        return axios.get(user_base_url   '/costings');
    }




}
export default new CostService();

This is Front end on React JS (StyleComponent.jsx)

import React, { Component } from 'react';
import {Row, Col, Card, Form, Button, Alert} from 'react-bootstrap';
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {faSignInAlt} from "@fortawesome/free-solid-svg-icons";
import CostService from '../services/CostService';
// import axios from 'axios';


class StyleComponent extends Component {
    constructor(props) {
        super(props);
        this.state = this.initialState;
        this.isValid = false
        this.addCost = this.addCost.bind(this);
    }


    initialState = {
        temp:null, cID:null, root:null, priMat1:null, priMat2:null, actSize:null, image:null, firstQuote:null, firstComm:null, secQuote:null, secComm:null, vendorTarget1:null, thirdQuote:null, thirdComm:null, vendorTarget2:null, fourthQuote:null, error:null, error_success:null, selectedFile:null
    };

    onFileChange = event => {
    
      // Update the state
      this.setState({ selectedFile: event.target.files[0] });
  };

  onFileChange = event => {
    
    // Update the state
    this.setState({ selectedFile: event.target.files[0] });
  
  };

  uploadFile = (rootID) => {
    

    
    
};

  componentDidMount() {

    // call cost API
    // call COST_IMAGE API
  }

    
    credentialChange = event => {
        this.setState({
            [event.target.name] : event.target.value
        });
    };
    
    addCost = () => {

        let cost = { 

            cID: this.state.cID, 
            root: this.state.root,
            priMat1: this.state.priMat1,
            priMat2: this.state.priMat2,
            actSize: this.state.actSize,
            image: this.state.image,
            firstQuote: this.state.firstQuote,
            firstComm: this.state.firstComm,
            secQuote: this.state.secQuote,
            secComm: this.state.secComm,
            vendorTarget1: this.state.vendorTarget1,
            thirdQuote: this.state.thirdQuote,
            thirdComm: this.state.thirdComm,
            vendorTarget2: this.state.vendorTarget2,
            fourthQuote: this.state.fourthQuote,
        };
        
        CostService.addCost(cost).then((res) => {
            console.log(res.data);
            this.state.temp= res.data;
            console.log(this.state.temp);
            console.log(this.state.selectedFile);
            CostService.uploadFile(this.state.selectedFile, res.data).then((res2) => {
              if(res2.data === 'SUCCESS') {
                console.log("Success");
                  this.setState({error_success:"The file has been uploaded!"});
              } else if(res2.data === 'FAILURE') {
                console.log("Failure");
                  this.setState({error:"The file could not be uploaded!"});
              }
          })
        })
    };

    resetRegisterForm = () => {
        this.setState(() => this.initialState);
    };

    render() {
      const {error, error_success} = this.state;

        return (
        <div>
          <br></br>
          <br></br>
          {error_success && <Alert variant="success">{error_success}</Alert>}
          {error && <Alert variant="danger">{error}</Alert>}
          <Card>
            <Card.Header className={"border border-light bg-light text-black"}>
              <FontAwesomeIcon icon={faSignInAlt}/> Add a New Style!
            </Card.Header>
          <br></br>
            <Form>
            <Row className="mb-3">
            &nbsp; &nbsp;
            <Form.Group as={Col} controlId="formGridcID">
                <Form.Label>Costing Tool ID</Form.Label>
                <Form.Control type="text" name="cID" placeholder="Enter Costing Tool ID" onChange={this.credentialChange}/>
              </Form.Group>
          
              <Form.Group as={Col} controlId="formGridRoot">
                <Form.Label>Style Number</Form.Label>
                <Form.Control type="text" name="root" placeholder="Enter Style Number Root" onChange={this.credentialChange}/>
              </Form.Group>


              <Form.Group as={Col} controlId="formGridPriMat1">
                <Form.Label>Primary Material</Form.Label>
                <Form.Control type="text" name ="priMat1" placeholder="Specify Primary Material" onChange={this.credentialChange}/>
              </Form.Group>

              <Form.Group as={Col} controlId="formGridPriMat2">
                <Form.Label>Secondary Material</Form.Label>
                <Form.Control type="text" name ="priMat2" placeholder="Specify Secondary Material" onChange={this.credentialChange}/>
              </Form.Group>

              <Form.Group as={Col} controlId="formGridSize">
                <Form.Label>Size Range</Form.Label>
                <Form.Control type="text" name ="actSize" placeholder="Specify Size Range" onChange={this.credentialChange}/>
              </Form.Group>

              <input className= "form-control chosen-select" type="file" onChange={this.onFileChange}/><br></br>

              &nbsp; &nbsp;
            </Row>
            <div align="right">
            &nbsp; &nbsp;
            <Button variant="outline-success" type="submit"
              onClick={this.addCost}>
                Register
            </Button>
            &nbsp; &nbsp;
            <Button variant="outline-primary" type="reset">
              Reset
            </Button>
            &nbsp; &nbsp;
            <br></br>
            <br></br> 
            </div>
            </Form>
          </Card>
         </div>
        );
    }
}

export default (StyleComponent);

This is the warning message on Springboot

2022-03-24 23:20:17.538  WARN 24028 --- [nio-8080-exec-5] .m.m.a.ExceptionHandlerExceptionResolver : Resolved [org.springframework.web.bind.MissingServletRequestParameterException: Required request parameter 'root' for method parameter type String is not present]

Please suggest how to post requests for both image-file and 'root'.

CodePudding user response:

Please change your upload file function to have multipart header and add the image, root as part of formData like below. (Updated the cost service file). Do let me know if the below solution works

import axios from 'axios';

const user_base_url = "http://localhost:8080/api";

class CostService{

    addCost(cost) {
        return axios.post(user_base_url   '/cost', cost);
    }

    uploadFile(image, root) {
       const config = {
           headers: { 'content-type': 'multipart/form-data' }
       }
       const formData = new FormData();
        formData.append('file', image);
        formData.append('root', root);
        return axios.post(user_base_url   '/cost_image_upload', formData, config);
    }

    showCost() {
        return axios.get(user_base_url   '/costings');
    }


}
export default new CostService();
  • Related