1

today I got some problem with my uploading images. I tried to upload 2 images from my front-end but on back-end got error its Error can't sent Header after they sent. When I just upload 1 image, I got no error but when I tried to upload 2 images, I got error. What I need to do? Should I use multipart/form-data?

I tried to use multipart/form-data but it didn't work

import {Link} from 'react-router-dom'

class Category extends React.Component{
    constructor(props){
        super(props);

        this.state={
            categoryId : this.props.match.params.id,
            dataCategory:[],
            categoryName:"",
            categoryDesc:"",
            categoryImage:"",
            categoryImageCabor:"",
            namaCabor :"",
            descCabor :"",
            imgCabor :"",
            imageCabor : "",
            selectedFile: null,
            imagePreviewUrl :"",
            file:""
        }
        this.handleSubmit = this.handleSubmit.bind(this);
        this.handleChange = this.handleChange.bind(this);
        this.imageHandleChange = this.imageHandleChange.bind(this);
    }
    componentWillMount(){
        this.getDetailsData();
    }

    getDetailsData(i){
        let categoryId = this.state.categoryId;

        fetch(`http://localhost:4000/get/${categoryId}`).then(res =>{
            if(res.status === 200)
                return res.json().then(resCategoryId =>{
                    console.log(resCategoryId);
                    this.setState({
                        id : resCategoryId._id,
                        namaCabor : resCategoryId.namaCabor,
                        descCabor : resCategoryId.descCabor,
                        imgCabor : resCategoryId.imgCabor,
                        imageCabor : resCategoryId.imageCabor
                    });
                });
            }).catch(err =>{
                if(err) console.log(err);
            })
    }


    imageHandleChange(e){
        e.preventDefault();

        let reader = new FileReader();
        let file = e.target.files[0];

        reader.onloadend = () =>{
            this.setState({
                file : file,
                imagePreviewUrl : reader.result
            });
        }
        reader.readAsDataURL(file);
    }


    handleSubmit(e){
        e.preventDefault();
        let {imagePreviewUrl} = this.state;
        const dataCategory = this.state.dataCategory;
        let categoryName = this.refs.categoryName.value;
        let categoryImage = this.refs.categoryImage.value;
        let categoryDesc =  this.refs.categoryDesc.value,
            categoryImageCabor = (<img alt="www.google.com" height="100px" src={imagePreviewUrl} />),
            namaCabor = this.refs.namaCabor.value,
            descCabor = this.refs.descCabor.value,
            imageCabor = (<img height="100px" src={this.state.imageCabor.props.src} />)

            fetch('http://localhost:4000/add', {
                mode:'cors',
                method:'post',
                headers:{
                    'Content-Type' : 'application/json',
                    "Accept" : "application/json",
                    "type" : "formData"
                },
                body:JSON.stringify({
                    categoryName : categoryName,
                    categoryDesc : categoryDesc,
                    categoryImage: categoryImage,
                    categoryImageCabor : categoryImageCabor,
                    namaCabor : namaCabor,
                    descCabor : descCabor,
                    imageCabor : imageCabor,
                    status : true
                }),
            }).then(res=>{
                return res.json();
            }).catch(function(err){
                if(err){
                    console.log(err);
                }
            })

        this.setState({
            dataCategory : dataCategory,
            imagePreviewUrl : false,
        });
        this.refs.myForm.reset();
        this.refs.myForm.focus();
    }
    handleChange(e){
        this.setState({
            [e.target.categoryName] : e.target.value,
            [e.target.categoryImage] : e.target.value,
            [e.target.categoryDesc] : e.target.value
        })
    }

    render(){

        let {imagePreviewUrl} = this.state;
        let $imagePreview = null;

        if(imagePreviewUrl){
            $imagePreview = (<img alt ="www.google.com" height="100px" src={imagePreviewUrl} />)
        }

        return this.state.imageCabor === "" ? <div></div> : (
            <div>
                <h3>Insert Category Cabang Olahraga </h3>
                <form style={{marginTop: 10}} ref="myForm" onSubmit={this.handleSubmit} encType="multipart/form-data" >
                    <div className="form-group">
                        <label>Nama Category</label>
                        <input
                            name="categoryName"
                            type="text"
                            className="form-control"
                            ref="categoryName"
                            onChange={this.handleChange}               
                        />
                        </div>

                        <div className="form-group">
                        <label>Deskripsi Category </label>
                        <textarea

                            name="categoryDesc"
                            type="text"
                            className="form-control"
                            ref="categoryDesc"
                            rows="5"
                            onChange={this.handleChange}
                        />
                        </div>

                        <div className="form-group">
                            <label>Upload Icon Image</label> <br />
                            <div>{$imagePreview}</div>
                        <input
                            name="categoryImage"
                            type="file"
                            ref="categoryImage"
                            className="image-control"
                            onChange={this.imageHandleChange}
                            />
                        </div>

                        <h1>Cabang Olahraga</h1>
                        <div className ="form-group">
                            <label>Nama Cabang Olahraga</label>
                        <input 
                            name="namaCabor"
                            type="text"
                            className="form-control"
                            ref="namaCabor"
                            value={this.state.namaCabor}
                            />
                        </div>

                        <div className ="form-group">
                            <label>Deskripsi Cabang Olahraga</label>
                        <textarea
                            name="descCabor"
                            type="text"
                            className="form-control"
                            ref="descCabor"
                            rows="5"
                            value={this.state.descCabor}
                            />
                        </div>

                        <div className="form-group">
                            <label>Icon Cabang Olahraga</label> <br />
                            <div><img height="100px" src={this.state.imageCabor.props.src} /></div>
                        </div>

                        <div className="form-group">
                            <input type="submit" value="Apply" className ="btn btn-primary" />
                        </div>

                </form>
            </div>
        );
    }
}

export default Category;

In my back-end got output. Error can't set headers after they are sent.

5
  • can you post the backend code? Commented May 21, 2019 at 6:29
  • app.post('/add', function(req, res){ // console.log(req.body); // upload(req, res, (err)=>{ const {categoryName, categoryDesc, categoryImage, categoryImageCabor, namaCabor, descCabor, imageCabor } = req.body; connectDb.collection('listCategoryCabangOlahraga').insertOne(req.body, function(err, result){ console.log(result.insertedCount +'data inserted'); if(err) console.log(err); }, res.send(req.body)); }); Commented May 21, 2019 at 6:37
  • sorry thats my backend its like mess if i copy here Commented May 21, 2019 at 6:38
  • If you are using mutler then please add the initiation of upload variable Commented May 21, 2019 at 7:45
  • alright thank you brother! i'll try, first thing i need to learn about multer first lol Commented May 21, 2019 at 7:47

2 Answers 2

1

You need to submit the formData to the server using FormData something like this

var formData = new FormData();
for (const file of this.state.files) {
  formData.append('file', file)
  formData.append('file2', file2)
  formData.append('file3', file3)
}

or you can write in easy way

var formData = new FormData();
formData.append('file', file)
formData.append('file2', file2)
formData.append('file3', file3)

Please change accordingly with your code

Make sure to set the header to multipart/form-data too

Cheers

Sign up to request clarification or add additional context in comments.

5 Comments

where should i put that variable formData?
In the place you submit the data to the server
i already tried to add formData but i got error that this.state.file its not iterable, sry im new to react js btw :(
Check my answer again and please adapt my code with your. Dont just copy and paste
i got it man, thanks. i have one question what did i need to add in node for uploading multiple images? i already reading that i need to use multer, is it true ?
0

I think Tony's answer is good enough, here are few things from my end to add multiple files:

you need to use formdata for this

var data = new FormData();
for (var x = 0; x < files.length; x++) {
    data.append("files" + x, files[x]);
}

to handle in nodejs: https://www.w3schools.com/nodejs/nodejs_uploadfiles.asp

I would suggest following library for enhancement (since they are specialised library one can always benefit from them)

Dropzone(for file uploads): https://github.com/react-dropzone/react-dropzone you can add restrictions by file size type etc

Axios(library for http request): https://github.com/axios/axios Convenient than using fetch

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.