the preacher
the preacher

Reputation: 377

using FormData() in react keeps returning null

I am building a React app and in it there's a part where i should set up a profile picture, but every time i call the api i keep getting an error that i haven't filled one of the fields for the post api to return a success response.

this is my jsx

<form>
    <input type="file" name="file" onChange={(e) => this.handleFile(e)}></input>
    <button type="button" onClick={(e) => this.handleUpload(e)} >send</button>
</form>

and here is the code i'm using to handle those

state = {
   file: null
};
handleFile(e) {
   console.log(e.target.files, "ssss");
    console.log(e.target.files[0], "ssss");
    let file = e.target.files

    this.setState({ file: e })
}
handleUpload(e) {
  let file = this.state.file
  let fromdata = new FormData();
  fromdata.append('image', file);
  fromdata.append('name', "filedata");
  const headers = {
        Authorization': localStorage.getItem('api_key'),

  }
  const user = {
       filedata: fromdata,
       type: 1,
  };
  axios.post(`sth sth`, user, {
       headers: headers
  })
       .then(res => {
           console.log(res);
           console.log(res.data);
        })
}


so basically the server requires type and filedata but every time i send an api request it keeps returning me

filedata: ["The filedata field is required."]

and i can't seem to find where the problem is.

Upvotes: 0

Views: 4020

Answers (2)

user3651521
user3651521

Reputation:

Assuming that you want to upload a single file, The problem I see is in setting the file to state. You are putting the entire response into the state in this statement: this.setState({ file: e }) change it to this.setState({ file: e.target.files[0] }).

Basically you are taking in more than just the file, you are taking in the entire response and other data that comes in when a user uploads a file using the choose file input button and because of that things can't be read well.

My practice: I would put the file into a global var instead of the state.

Usually in cases like this, its the function that doesn't complete but the main thread keeps on running, thats why variables state null or older value.

var file, fromdata;

handleFile(e) {
    file = e.target.files[0];
}
handleUpload(e) {
    fromdata = new FormData(); //make sure this statement completes before moving any further
    fromdata.append('image', file);
    fromdata.append('name', "filedata");
    const headers = {
        Authorization': localStorage.getItem('api_key'),

    }
    user = {
        filedata: fromdata,
        type: 1,
    };
    axios.post(`sth sth`, user, {
        headers: headers
    })
        .then(res => {
            console.log(res);
            console.log(res.data);
        })
}

Upvotes: 1

BoyePanthera
BoyePanthera

Reputation: 614

Work on your handleFile function properly and add a Content-Type/Accept header to your api request, your final code should look something like this. on your api console.log (req.file) you should see your file now reaches server successfully, or if you can provide a bit of your server code, I can be able to help further.

import React from 'react';
import axios from 'axios';

export class Test extends React.Component {
    constructor(props){
        super(props);
        this.state = {
            file : null
        }
        this.handleFile = this.handleFile.bind(this)
        this.handleUpload = this.handleUpload.bind(this)
    }

    handleFile(e) {
        let file = e.target.files[0]
        this.setState({ file })
    }

    handleUpload (e) {
        e.preventDefault();
        let file = this.state.file
        let fromdata = new FormData();
        fromdata.append('image', file);
        const headers = {
                'Authorization': localStorage.getItem('api_key'),
                'Content-Type' : 'multipart/form-data'
        }
        const user = {
            filedata: fromdata,
            type: 1,
        };
        axios.post(`sth sth`, user, {
            headers
        })
       .then(res => {
           console.log(res);
           console.log(res.data);
        })
    }


    render() {
        return (
            <form onSubmit={this.handleUpload}>
                <label>File</label><br/>
                    <input type='file' onChange={this.handleFile}/>
                <button>Send File!</button>
            </form>
        )
    }
}

Upvotes: 1

Related Questions