Home > Software design >  formData cannot arrive to backend
formData cannot arrive to backend

Time:01-09

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,

  1. 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"

  2. 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"

  3. 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

  • Related