2

I'm having trouble uploading files from react to a laravel api. I have a backend for uploading a post that has title,body and image. if their is an image it should save the url of the image and if not save a default value. i tested with postman and it worked correctly but when i'm trying to upload from my react front end, it saves noimage for every trial.

Laravel api

public function save(Request $request)
    {
        $validator = Validator::make($request->all(),[
            'title'=>'required',
            'body'=>'required',
            'user_id'=>'required'
        ]);
        $post = new Post();
            $post->title = $request->title;
            $post->body= $request->body;
            $post->user_id= auth()->user()->id;
            if($request->hasFile('image')){
                $fileNameWithExt = $request->file('image')->getClientOriginalName();
                $fileName = pathinfo($fileNameWithExt,PATHINFO_FILENAME);
                $fileExt = $request->file('image')->getClientOriginalExtension();
                $fileNameToStore = $fileName.'_'. time() .'.'.$fileExt;
                $path = $request->file('image')->storeAs('public/images',$fileNameToStore);
            }else{
                $fileNameToStore = "NoImage.jpg";
            }
            $post->image =$fileNameToStore;
            $post->save();

        return new PostResource($post);
    }

React code

    const [imgName,setImgName] = useState('Choose Image');
        const [postImg,setPostImg] = useState()
        const [postData,setPostData] = useState({
            title:'',
            body:''
        });
    
        const {title,body} = postData;
    
        const changeHandler = e =>{  
           setPostData({...postData,[e.target.name]:e.target.value});
        }
    
        const fileHandler = e=>{
            setImgName(e.target.files[0].name);
            setPostImg(e.target.files[0]);
            
        }
    
        const submitHandler = e =>{
            e.preventDefault();
            
            if(!title || !body){
                props.setMsg("You can't leave title or body field blank",'warning');
                setTimeout(()=>{
                    props.clearError()
                },3000)
            }else{
                const fd = new FormData();
                fd.append('image',postImg)
                const data = {
                    title:title,
                    body:body,
                    image:fd
                }
                
                props.onCreatePost(data);
                console.log(fd.get('image'));
                
            }
           
        }

I'm using redux to with react

`

export const createPost = (formData)=>{
    return (dispatch) =>{
        const token = localStorage.getItem('token')
        const config ={
            headers:{
                'Authorization':`Bearer ${token}`,
                
            }, 
        }
        console.log('Sent Data: ',formData);
           axios.post(`http://127.0.0.1:8000/api/posts`,formData,config)
            .then(res=>{
                dispatch(addPost(res.data))
            }).catch(err=>{
                dispatch(postfailed(err.response))
            })        
    }
}

`

9
  • Please post code which uploads the image to your backend. Commented Sep 22, 2020 at 13:46
  • 1
    It's not clear when your code post the data to your backend. You have declared formdata but seems not used which ``props.onCreatePost(data);``` submit data object to a method whose definition is not available Commented Sep 22, 2020 at 14:17
  • 1
    export const createPost = (formData)=>{ return (dispatch) =>{ const token = localStorage.getItem('token') const config ={ headers:{ 'Authorization':Bearer ${token}, }, } console.log('Sent Data: ',formData); axios.post(127.0.0.1:8000/api/posts,formData,config) .then(res=>{ dispatch(addPost(res.data)) }).catch(err=>{ dispatch(postfailed(err.response)) }) } } Commented Sep 22, 2020 at 14:17
  • Please add this to your question so it's more readable. Commented Sep 22, 2020 at 14:18
  • 2
    I have done that, Thank you this is my first time of asking question here Commented Sep 22, 2020 at 14:25

2 Answers 2

3

You need to send the request as multipart/form-data if you need to include files in your post request:

const config ={
    headers:{
        'Authorization':`Bearer ${token}`,
         'Content-Type': 'multipart/form-data'
     }, 
}

If you want to learn more about the subject I suggest you read this: application/x-www-form-urlencoded or multipart/form-data?


Also, you must attach every field as formData, you can't create a javascript object with a formdata inside

Instead of:

const fd = new FormData();
fd.append('image',postImg)
const data = {
   title:title,
   body:body,
   image:fd
}
                
props.onCreatePost(data);

Do:

const fd = new FormData();
fd.append('image',postImg)
fd.append('title', title)
fd.append('body', body)             
props.onCreatePost(fd);

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

2 Comments

this method didnt work. i get an error that I'm trying to insert empty data in the database
I edited my answer, didn't see that you were not using the formData object
0

Please update your formdata to following

const fd = new FormData();
fd.append('image',postImg)
fd.append('title', title)
fd.append('body',body)
props.onCreatePost(fd);

Then use header as explained by @gbalduzzi

1 Comment

Wow. it worked thank you very much, i'm really grateful

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.