1
votes

The job is very simple: Take postTitle, postBody and postImage as input and update them in database. But I am facing difficulties uploading the image, hope someone will help me. I am using InertiaJs, React and Laravel.

My EditPost.jsx file:

import {React, useState, useEffect} from 'react'
import Layout from '../Shared/Layout'
import { useForm } from '@inertiajs/inertia-react'

function EditPost({errors, postId, postTitle, postBody, postImage}) {
    const { data, setData, put, progress } = useForm({
        postTitle: postTitle,
        postBody: postBody,
        postImage: null
    })

    const onSubmitHandler = (e) => {
        e.preventDefault()
        put('/posts/update/' + postId)
    }

    return (
        <div className="container">
            <div className="row justify-content-center">
                <div className="col-md-8">
                    <br/>
                    <br/>
                    <h3 className="text-center">Edit the post</h3>
                    <form onSubmit={onSubmitHandler}>
                        <div className="mb-3">
                            <label htmlFor="postTitle" className="form-label">Post title</label>
                            <input value={data.postTitle} onChange={e => setData('postTitle', e.target.value)} type="text" className="form-control" id="postTitle" placeholder="Enter post title here..." />
                            {errors.postTitle && <p className="text-danger">{errors.postTitle}</p>}
                        </div>
                        <div className="mb-3">
                            <label htmlFor="postBody" className="form-label">Post body</label>
                            <input value={data.postBody} onChange={e => setData('postBody', e.target.value)} type="text" className="form-control" id="postBody" placeholder="Enter post body here..." />
                            {errors.postBody && <p className="text-danger">{errors.postBody}</p>}
                        </div>
                        <div className="mb-3">
                            <label htmlFor="postImage" className="form-label">Post body</label>
                            <input type="file" className="form-control" id="postImage" value={data.postImage} onChange={e => setData('postImage', e.target.files[0])}  />
                            {errors.postImage && <p className="text-danger">{errors.postImage}</p>}
                        </div>
                        {progress && (
                            <progress value={progress.percentage} max="100">{progress.percentage}%
                        </progress>
                        )}
                        <br/>
                        <button className="btn btn-success rounded">Submit</button>
                    </form>
                </div>
            </div>
        </div>    
    )
}

EditPost.layout = page => <Layout pageTitle={'Edit the Post'} children={page}/>

export default EditPost

I am following the InertiaJS documentation but getting this warning in console:

Warning: `value` prop on `input` should not be null. Consider using an empty string to clear the component or `undefined` for uncontrolled components.
    [.......]

If I ignore the error and select file, I get the following errors:

Uncaught DOMException: Failed to set the 'value' property on 'HTMLInputElement': This input element accepts a filename, which may only be programmatically set to the empty string.

react_devtools_backend.js:2556 Warning: A component is changing an uncontrolled input of type file to be controlled. Input elements should not switch from uncontrolled to controlled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component.

Uncaught DOMException: Failed to set the 'value' property on 'HTMLInputElement': This input element accepts a filename, which may only be programmatically set to the empty string.

Please help me out...

1
you are also missing enctype="multipart/form-data" on your form, you need this when allowing files - Michael Mano
@Codenewbie Then it gives another error, it says: Uncaught DOMException: Failed to set the 'value' property on 'HTMLInputElement': This input element accepts a filename, which may only be programmatically set to the empty string. - Fariaz Khan

1 Answers

0
votes

Try using POST instead of PUT, otherwise you would need to spoof the method.

Also if the version of Inertia you are using is below 0.8.0, you will need to pass the information as a FormData object.

Uploading files using a multipart/form-data request is not natively supported in some languages for the put, patch or delete methods. The workaround here is to simply upload files using post instead.

Check out the page on Inertia file uploads here which has a React example.