-1

i have a problem with my code when I try to upload a file with reactjs and laravel for backend, after click submit button server response with 500 IS error,looking forward inside code i get message Call to a member function getClientOriginalName() on null, I guess error appear because of my js function, so hopefully someone can help me finger it out, i am appreciate it

my react component :

constructor(){
    super();
    this.fileInput = React.createRef();
    this.state = {
        name: '',
        avatar: '',
    }
}

handleNameChange(e){
    this.setState({
        name: e.target.value
    })
}


handleAvatarChange(e){
    this.setState({
        avatar:this.fileInput.current.files[0].name
    })
}


handleSubmit(e){
    e.preventDefault();
    axios.post('/api/add', this.state).then(response => {
        console.log(response)

    }).then(error => {
        console.log(error)
    })
}

render(){
    return (
        <div>
            <a href="/">home</a>
            {/*<Link to="/" className="btn btn-success">Return to Items</Link>*/}
            <form className="form-horizontal" onSubmit={this.handleSubmit.bind(this)}>
                <input type="text" className="form-control" id="name" value={this.state.name}  onChange={this.handleNameChange.bind(this)}/>

                <input type="file" ref={this.fileInput} onChange={this.handleAvatarChange.bind(this)} /><br></br>
                <button type="submit" className="btn btn-default">Save</button>
            </form>
        </div>
    )

}

}

my controller:

public function store(Request $request){
    $file_name_image = $request->file('avatar')->getClientOriginalName();
    $user = new User();

    $user->name = $request->name;
    $user ->avatar = $file_name_image;
    $request->file('avatar')->move('upload/',$file_name_image);
    $user->save();
    return response()->json('Successfully added');
}
Duc Pham
  • 19
  • 7

3 Answers3

0

I think the problem in your input tag. Input doesn't have name attribute. You should add it.

    <input name="file" type="text" className="form-control" id="name" value={this.state.name}  onChange={this.handleNameChange.bind(this)}/>

And I recommend you add IF statement in yours controller.

    if ($request->hasFile('file')) {
       //
    }
0

I can not comment, so I will write the answer here. So you can find the answer for your original question here: How do I set multipart in axios with react?

If you want to send other data than file too, you just simply add it like you did with the file. for example:

formData.append('name', 'Your new name')

first parameter is the name you want for the POST data key, the second one is the data you want to send. It can come from the state etc.

Gary
  • 61
  • 3
0

for anyone else who may need, thank all!

   constructor(props) {
    super(props);
    this.state ={
        file:null,
        name:'',
    }
    this.onFormSubmit = this.onFormSubmit.bind(this)
    this.onChange = this.onChange.bind(this)
    this.fileUpload = this.fileUpload.bind(this)
    this.handleNameChange = this.handleNameChange.bind(this)
}

onFormSubmit(e){
    e.preventDefault() // Stop form submit
    this.fileUpload(this.state.file,this.state.name).then((response)=>{
        console.log(response.data);
    })
}

onChange(e) {
    this.setState({file:e.target.files[0]})
}

handleNameChange(e){
    this.setState({
        name: e.target.value
    })
}


fileUpload(file, name){
    const url = 'http://localhost:8000/api/add';
    const formData = new FormData();
    formData.append('file',file);
    formData.append('name', name);
    const config = {
        headers: {
            'content-type': 'multipart/form-data'
        }
    }
    return  post(url, formData,config)
}

render() {
    return (
        <form onSubmit={this.onFormSubmit}>
            <h1>File Upload</h1>
            <input type="text" value={this.state.name}  onChange={this.handleNameChange}/>
            <input type="file" onChange={this.onChange} />
            <button type="submit">Upload</button>
        </form>
    )
}
Duc Pham
  • 19
  • 7