[HELP] Can't upload file from a nuxtjs form to strapibackend please help

System Information
  • Strapi Version: “3.3.4”
  • Operating System: Windows 10
  • Database: PostgreSQL
  • Node Version: “14.x”,
  • NPM Version: “6.0.0”

Hi, I have my strapi server deployed in Heroku and i have a form with some text’s fileds and one files field.
Without the files field the form work fine and the information is posted in my backend, but i tried to to upload a file and can’t.

Can someone please explain me what im doing wrong? I coudln’t find a working example or a solution online. please help me…

my code:

<template>

  <section style="background-color: rgb(228, 235, 235)" id="hiringsection">

    <div class="container py-5">

      <div class="row py-5">

        <div class="col-md-6">

          <h1>{{ pageinfo.subtitle }}</h1>

          <p>{{ pageinfo.subcontent }}</p>

        </div>

        <div class="col-md-6">

          <div

            v-if="success"

            class="rounded bg-indigo-500 text-white text-lg p-4"

          >

            Great! Your message has been sent successfully. I will try to

            respond quickly.

          </div>

          <form v-else v-on:submit.prevent="sendMessage" class="form-container">

            <div v-if="errored" class="rounded bg-red-200 text-lg p-4">

              Bummer, Something went wrong. Did you fill out all of the fields?

            </div>

            <div class="col-md-12">

              <div class="form-group"></div>

            </div>

            <div class="container w-100">

              <div class="row">

                <div class="col-md-12">

                  <h3>{{ pageinfo.subtitle2 }}</h3>

                  <h1 class="pb-5">{{ pageinfo.subcontent2 }}</h1>

                </div>

                <div class="col-md-6">

                  <div class="form-group">

                    <input

                      v-model="name"

                      required

                      name="name"

                      id="first_name"

                      placeholder="First Name*"

                      class="form-control rounded-0"

                    />

                  </div>

                </div>

                <div class="col-md-6">

                  <div class="form-group">

                    <input

                      v-model="surname"

                      required

                      name="surname"

                      id="surname"

                      class="form-control rounded-0"

                      placeholder="Surname *"

                    />

                  </div>

                </div>

                <div class="col-md-6">

                  <div class="form-group">

                    <input

                      v-model="email"

                      required

                      name="email"

                      id="email"

                      class="form-control rounded-0"

                      placeholder="E-mail *"

                    />

                  </div>

                </div>

                <div class="col-md-6">

                  <div class="form-group">

                    <input

                      id="phone"

                      v-model="phone"

                      required

                      class="form-control"

                      name="phone"

                      placeholder="Phone *"

                    />

                  </div>

                </div>

                <div class="col-md-12">

                  <div class="form-group">

                    <input

                      required

                      name="position"

                      id="position"

                      class="form-control rounded-0"

                      readonly=""

                      :value="`${pageinfo.video}`"

                    />

                  </div>

                </div>

                <div class="col-md-12">

                  <div class="form-group">

                    <input

                      v-model="educational_establishment"

                      required

                      name="Educational_establishment"

                      id="Educational_establishment"

                      class="form-control rounded-0"

                      placeholder="School/University*"

                    />

                  </div>

                </div>

                <div class="col-md-12">

                  <div class="form-group">

                    <input

                      v-model="education_level"

                      required

                      class="form-control"

                      name="education_level"

                      id="education_level"

                      placeholder="Education Level*"

                    />

                  </div>

                </div>

                <div class="col-md-12">

                  <div class="form-group">

                    <label for="presentation">Motivation*</label>

                    <textarea

                      name="motivation"

                      id="motivation"

                      class="form-control rounded-0"

                      cols="30"

                      rows="4"

                      v-model="motivation"

                      required

                    ></textarea>

                    <div id="charNum"></div>

                  </div>

                </div>

                <div class="col-md-12">

                  <div class="form-group">

                    <label for="cv">Curriculum</label>

                    <input

                      type="file"

                      class="form-control-file"

                      id="cv"

                      name="cv"

                    />

                  </div>

                </div>

                <div class="col-md-12">

                  <div class="form-group form-check">

                    <input

                      type="checkbox"

                      name="privacypolicy"

                      class="form-check-input"

                      id="privacypolicy"

                      v-model="privacypolicy"

                      required

                    />

                    <label class="form-check-label" for="rgpd"

                      >By submitting this form I hereby agree with

                      <a href="/terms_of_service" target="_blank"

                        >'s privacy policy</a

                      ></label

                    >

                  </div>

                </div>

                <div class="col-md-12">

                  <div class="form-group">

                    <button

                      type="submit"

                      class="btn btn-p w-100 rounded-0 py-3 shadow"

                    >

                      Submit

                    </button>

                  </div>

                </div>

              </div>

            </div>

          </form>

        </div>

      </div>

    </div>

  </section>

</template>

<script>

export default {

  data() {

    return {

      pageinfo: [],

      loading: false,

      success: false,

      errored: false,

      name: "",

      surname: "",

      email: "",

      phone: "",

      position: "",

      educational_establishment: "",

      education_level: "",

      motivation: "",

      cv: "",

      privacypolicy: "",

    };

  },

  methods: {

    sendMessage() {

      this.loading = true;

      this.$http

        .post("hiring-requests", {

          name: this.name,

          surname: this.surname,

          email: this.email,

          phone: this.phone,

          position: this.position,

          educational_establishment: this.educational_establishment,

          education_level: this.education_level,

          motivation: this.motivation,

          privacypolicy: this.privacypolicy,

          cv: this.cv

        })

        .then((response) => {

          this.success = true;

          this.errored = false;

        })

        .catch((error) => {

          this.errored = true;

        })

        .finally(() => {

          this.loading = false;

        });

//added this code to my cv work: 

      const formElement = document.querySelector("form");

      formElement.addEventListener("submit", (e) => {

        e.preventDefault();

        const request = new XMLHttpRequest();

        request.open("POST", "hiring-requests");

        request.send(new FormData(formElement));

      });

    },

  },

//ignore

  async fetch() {

    this.pageinfo = await this.$http.$get("pages/14");

  },

};

</script>

<style lang="scss" scoped>

</style>

Instead of cv you need to use files. Strapi uses files by default to accept uploaded files.

1 Like

Hi! Thanks for responding,

Do you mean in the Html or the script?

CV is the name of the file atribute of my collection

This is a sample in React:
You have to submit formData with a files field and a data field containing your JSON request.
In this case Photos is a Strapi content type that as a file field.

    const formdata = new FormData();
    formdata.append("data", '{"description": "My JSON DATA"}');
    formdata.append("files.file", files[0], files[0].name);

    fetch("http://localhost:1337/photos", {
      method: "POST",
      body: formdata,
    });

Be sure to check this repo for demo: GitHub - chris-sev/unsplash-clone-next

1 Like

Working with:

methods: {
    sendToStrapi() {
      this.loading = true;
      let form = this.$refs["uploadForm"];
      let formData = new FormData();
      let formElements = form.elements;
      let data = {};
      formElements.forEach((currentElement) => {
        if (!["submit", "file"].includes(currentElement.type)) {
          data[currentElement.name] = currentElement.value;
        } else if (currentElement.type === "file") {
          if (currentElement.files.length === 1) {
            const file = currentElement.files[0];
            formData.append(files.${currentElement.name}, file, file.name);
          } else {
            for (let i = 0; i < currentElement.files.length; i++) {
              const file = currentElement.files[i];
              formData.append(files.${currentElement.name}, file, file.name);
            }
          }
        }
      });
      formData.append("data", JSON.stringify(data));
      this.$http
        .post("MINHAAPI", formData)
        .then((response) => {
          this.success = true;

          this.errored = false;
        })

        .catch((error) => {
          this.errored = true;
        })

        .finally(() => {
          this.loading = false;
        });
    },
  },

and using “ref=“uploadForm”” in form tag

if anyone need the fulll code just ping me :slight_smile: let’s go :rocket:

1 Like