I'm trying to make a team section, that it is a dynamic form. You can insert team members as much as you want, and it includes, "memberName", "memberDescription", "memberJobTitle", "images"
.
Really do not understand why but something is wrong in the frontend, somehow file does not arrive to backend, when I submit to create a team member, I got this message:
message: "Cannot read properties of undefined (reading 'path')
However,
When I try upload file to team member on Postman with form-data, it works. So, I assume problem is not in the backend.
team[0][memberName]: "Lala" team[0][memberJobTitle]: "Lala" team[0][images][0]: "image.jpg" team[0][memberDescription]: "Lala"
In the frontend, I can see the file that I uploaded when I submit in
console.log(values)
.team: Array(1) 0: images:Array(1) 0: FileList {0: File, length: 1} length: 1 [[Prototype]]: Array(0) memberDescription: "work with us 5 years long" memberJobTitle: "marketing" memberName: "Jane Doe"
If I log
console.log("append image: ", item.images[0]);
it also shows me a FileList.FileList {0: File, length: 1} 0: File {name: 'real-estate-logo-template_1195-19.jpg.webp', lastModified: 1672667306966, lastModifiedDate: Mon Jan 02 2023 13:48:26 GMT 0000 (Western European Standard Time), webkitRelativePath: '', size: 9894, …} length: 1
submitHandler
const submitHandler = async (values) => {
const formData = new FormData();
// append other fields
values.team = values.team || [{}];
values.team.forEach((item, index) => {
formData.append(`team[${index}][memberName]`, item.memberName || "");
//append other team fields
formData.append(`team[${index}][images][0]`, item.images[0]);
console.log("append image: ", item.images[0]);
});
await axios({
method: "POST",
url: `http://localhost:8080/api/pages/${pageId}/aditional-section`,
data: formData,
headers: {
"Content-Type": "multipart/form-data",
Authorization: "Bearer " localStorage.getItem("token"),
},
})
.then((res) => {
console.log(res);
})
.catch((res) => {
console.log(res);
});
console.log(values);
};
I'm using Formik to handle form.
<FieldArray name="team">
{({ insert, remove, push }) => (
<div>
{values.team.length > 0 &&
values.team.map((item, index) => (
<div className="row" key={index}>
<div className="col">
<label htmlFor={`team.${index}.images[0]`}>
Upload image
</label>
{/* <Field
name={`team.${index}.images`}
type="file"
/> */}
<FileInput
name={`team.${index}.images[0]`}
type="file"
value={undefined}
/>
<ErrorMessage
name={`team.${index}.images[0]`}
component="div"
className="field-error"
/>
</div>
</div>
))}
<button
type="button"
className="secondary"
onClick={() =>
push({
memberName: "",
memberJobTitle: "",
memberDescription: "",
images: "",
})
}
>
Add Member
</button>
</div>
)}
</FieldArray>
CodePudding user response:
MDN Docs states:
value
The field's value. This can be a string or Blob (including subclasses such as File). If none of these are specified the value is converted to a string.
It appears that the FileList
type isn't supported but the File
type is. Try looping through the FileList
and appending each file to the formData
like so.
const submitHandler = async (values) => {
...
values.team.forEach((item, index) => {
formData.append(`team[${index}][memberName]`, item.memberName || "");
//append other team fields
// Before
// formData.append(`team[${index}][images][0]`, item.images[0]);
// After - Loop through images, and append the File
for (let i = 0; i < item.images[0].length; i ) {
const file = item.images[0].files[i];
formData.append(`team[${index}][images][0]`, file);
}
console.log("append image: ", item.images[0]);
});
...
};
This should work, granted your backend is set up to receive multiple files.
CodePudding user response:
are you sure that it is not a Cross authorization problem ?
in your backend application you need to enable Cross
to allow requests from other urls