Search code examples
laravelapihttp-headershttp-postvuejs3

Axios post request error when sending an array with an image


I have a form that has an array input and an image, when sending the request without the image it's getting stored correctly in the database, when the image input and the "Content-Type": "multipart/form-data" header both added, it send the request with the correct data but it outputs that the array data is invalid.

the code is written in Vue 3 and the backend is a laravel api.

    <script>
import axios from "axios";

export default {
  name: "AddPayloadModel",

  data() {
    return {
      drone_id: [],
      drone_models: [],
      image: null,
      previewImage: null,
    };
  },
  created() {
    this.getDroneModels();
  },
  methods: {
    getDroneModels() {
      axios.get("http://127.0.0.1:8000/api/drone-models").then((response) => {
        this.drone_models = response.data;
      });
    },
    imgUpload(e) {
      this.image = e.target.files[0];
      const reader = new FileReader();
      reader.readAsDataURL(this.image);
      reader.onload = (e) => {
        this.previewImage = e.target.result;
      };
    },
    submit(e) {
      const form = new FormData(e.target);

      const inputs = Object.fromEntries(form.entries());

      inputs.drone_id = Object.values(this.drone_id);

      console.log(inputs.drone_id);

      axios
        .post("http://127.0.0.1:8000/api/payload-model/add", inputs, {
          headers: {
            "Content-Type": "multipart/form-data",
          },
        })
        .then((res) => {
          if (res.data.isUnattachableDrones) {
            console.log(res);
            alert(res.data.unattachableDrones);
          } else {
            this.$router.push("/home");
          }
        })
        .catch((e) => {
          console.error(e);
        });
    },
  },
};
</script>

<template>
  <main class="form-signin">
    <form @submit.prevent="submit">
      <h1 class="h3 mb-3 fw-normal">Add Payload Model</h1>

      <div class="form-floating">
        <input
          class="form-control"
          autocomplete="off"
          name="brand_name"
          placeholder="Brand Name"
        />
        <label>Brand Name</label>
      </div>

      <div class="form-floating">
        <input
          class="form-control"
          autocomplete="off"
          name="model_name"
          placeholder="Model name"
        />
        <label>Model Name</label>
      </div>

      <div class="form-floating">
        <input
          class="form-control"
          autocomplete="off"
          name="type"
          placeholder="Type"
        />
        <label>Type</label>
      </div>

      <select
        v-model="drone_id"
        multiple="multiple"
        name="drone_id"
        style="height: auto"
        class="form-select last-input"
      >
        <template v-for="drone in drone_models">
          <option :value="drone.id">
            {{ drone.brand_name }}
          </option>
        </template>
      </select>

      <input
        name="image"
        ref="fileInput"
        accept="image/*"
        type="file"
        @input="imgUpload"
      />

      <button class="w-100 btn btn-lg btn-form" type="submit">Submit</button>
    </form>
  </main>
</template>

here is the response when submitting the form. enter image description here

and here is the payload. enter image description here


Solution

  • It got solved by changing the way to push data to the post request to a formData and append it manually like this.

    submit() {
      const formData = new FormData();
      formData.append(
        "brand_name",
        document.getElementById("brand_name").value
      );
      formData.append(
        "model_name",
        document.getElementById("model_name").value
      );
      formData.append("type", document.getElementById("type").value);
      formData.append("image", document.getElementById("image").files[0]);
    
      this.drone_id.forEach((drone_id) => {
        formData.append("drone_id[]", drone_id);
      });
    
      const headers = { "Content-Type": "multipart/form-data" };
    
      axios
        .post("http://127.0.0.1:8000/api/payload-model/add", formData, headers)
        .then((res) => {
          console.log(res);
          if (res.data.isUnattachableDrones) {
            console.log(res);
            alert(res.data.unattachableDrones);
          } else {
            this.$router.push("/home");
          }
        })
        .catch((e) => {
          console.error(e);
        });
    },