import React from 'react'
import { useForm } from '@inertiajs/inertia-react'
const { data, setData, post, progress } = useForm({
image: null,
})
function submit(e) {
e.preventDefault()
post('/users')
}
return (
<form onSubmit={submit}>
<input type="file" value={data.image} onChange={e => setData('image', e.target.files[0])} />
{progress && (
<progress value={progress.percentage} max="100">
{progress.percentage}%
</progress>
)}
<button type="submit">Submit</button>
</form>
)
Mar 13, 2022
5
Level 2
File upload error inertia.js and react.js
I'm trying to upload an image along with some content using Inertia & React. The content I can upload fine however I'm getting an error while trying to upload the image.
{"image":"The image must be an image."}
EDIT: after debugging for a bit I think it's more typescript issue than inertia.
My main form component / page:
interface Props {
auth: any;
}
interface FormProps {
title: string;
intro: string;
image: FileList | undefined;
published_date: string;
}
const Create = ({ auth }: Props) => {
const { data, setData, processing, errors } = useForm<FormProps>({
title: "",
intro: "",
image: undefined,
published_date: "",
});
const handleFile = (e: React.ChangeEvent<HTMLInputElement>) => {
let file = e.target.files;
if (file !== undefined) {
setData("image", file);
}
};
const submit = (e: React.SyntheticEvent) => {
e.preventDefault();
{
console.log(data);
}
Inertia.post("admin.blogs.store");
};
return (
<Authenticated auth={auth}>
<Container>
<Heading type={"h3"}>Create a post</Heading>
<form onSubmit={submit} noValidate>
<Row layout="inline">
<Label input={"title"} value={"Title"} required={true}>
<Input
type="text"
name="title"
value={data.title}
required={true}
onChange={(e) =>
setData("title", e.target.value)
}
/>
{errors.title && (
<InputError error={errors.title} />
)}
</Label>
<Label
input={"published_date"}
value={"Date"}
required={true}
>
<Input
type="date"
name="published_date"
value={data.published_date}
required={true}
onChange={(e) =>
setData("published_date", e.target.value)
}
/>
{errors.published_date && (
<InputError error={errors.published_date} />
)}
</Label>
</Row>
<Row>
<Label input={"intro"} value={"Intro"} required={true}>
<Textarea
name="intro"
value={data.intro}
required={true}
onChange={(e) =>
setData("intro", e.target.value)
}
/>
{errors.intro && (
<InputError error={errors.intro} />
)}
</Label>
</Row>
<Row>
<Label input={"image"} value={"Image"} required={true}>
<Input
type="file"
name="image"
value={data.image}
required={true}
onChange={handleFile}
/>
{errors.image && (
<InputError error={errors.image} />
)}
</Label>
</Row>
<Row>
<Button
processing={processing}
type={"submit"}
color={"primary"}
>
Publish Blog
</Button>
</Row>
</form>
</Container>
</Authenticated>
);
};
export default Create;
My Input component:
const Input = styled("input", {
width: "100%",
height: "45px",
background: "$white",
color: "$black",
textIndent: "10px",
border: "1px solid $grey",
borderRadius: "5px",
paddingRight: "10px",
});
interface Props {
type: string;
name: string;
value: string;
required?: boolean;
onChange: React.ChangeEventHandler<HTMLInputElement>;
}
export default ({ type, name, value, required, onChange }: Props) => {
const input = useRef<HTMLInputElement>(null);
return (
<Input
type={type}
name={name}
value={value}
ref={input}
required={required}
onChange={(e) => onChange(e)}
/>
);
};
I get a compile error of Type 'FileList' is not assignable to type 'string'.
When I try to upload an image I get the following error in my console
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.
at HTMLInputElement.set [as value]
If I add FileList to the value type on my input like this value: string | FileList; I then get the following errors.
TS2769: No overload matches this call.
Overload 1 of 3, '(props: Omit<Pick<DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, "key" | keyof InputHTMLAttributes<...>> & { ...; }, "css" | "as"> & TransformProps<...> & { ...; }): ReactElement<...>', gave the following error.
Type 'string | FileList' is not assignable to type 'string | number | readonly string[]'.
Type 'FileList' is not assignable to type 'string | number | readonly string[]'.
Type 'FileList' is missing the following properties from type 'readonly string[]': concat, join, slice, indexOf, and 17 more.
Overload 2 of 3, '(props: Omit<Pick<DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, "key" | keyof InputHTMLAttributes<...>> & { ...; }, "css" | "as"> & TransformProps<...> & { ...; }): ReactElement<...>', gave the following error.
Type 'string | FileList' is not assignable to type 'string | number | readonly string[]'.
Overload 3 of 3, '(props: Omit<Pick<DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, "key" | keyof InputHTMLAttributes<...>> & { ...; }, "css"> & TransformProps<...> & { ...; }): ReactElement<...>', gave the following error.
Type 'string | FileList' is not assignable to type 'string | number | readonly string[]'.
Please or to participate in this conversation.