13

I have a few application, when I am sending formdata using axios post data is successfully sent to API. but when i am using put request its not working with formData.

<template>
  <div class="container">
    <div class="container-fluid" style="background:#fff">
      <div class="page-header">
        <h4 class="page-title">
          <i class="flaticon-users"></i> Leads
        </h4>
        <ul class="breadcrumbs">
          <li class="nav-home">
            <a href="/">
              <i class="flaticon-home"></i>
            </a>
          </li>
          <li class="separator">
            <i class="flaticon-right-arrow"></i>
          </li>
          <li class="nav-item">
            <router-link to="/leads">Leads</router-link>
          </li>
          <li class="separator">
            <i class="flaticon-right-arrow"></i>
          </li>
        </ul>
      </div>
      <template>
        <div class="btn-wrapper">
          <button v-on:click="seen = !seen" class="btn btn-primary btn-md">
            <i class="flaticon-interface-1"></i>Add New Lead
          </button>
        </div>
        <p></p>
      </template>
      <div class="row">
        <div class="col-md-12" v-if="!seen">
          <div class="card">
            <div class="card-header">
              <h4 class="card-title">
                <i class="flaticon-interface-1"></i> New Leads
              </h4>
            </div>
            <div class="card-body">
              <form
                @submit.prevent="addLeads"
                id="leadform"
                class="mb-3"
                enctype="multipart/form-data"
              >
                <div class="col-md-12">
                  <div class="row">
                    <div class="col-md-6">
                      <label>Lead</label>
                      <div class="form-group">
                        <input
                          type="text"
                          id="name"
                          name="lead_name"
                          class="form-control"
                          placeholder="Lead Name"
                          v-model="form.name"
                        >
                        <template v-if="errors">
                          <span v-for="(fieldsError, fieldName) in errors" :key="fieldName">
                            <template v-if="fieldName == 'name'">
                              <p class="errors">
                                <strong>{{ fieldsError.join('\n') }}</strong>
                              </p>
                            </template>
                          </span>
                        </template>
                      </div>
                    </div>

                    <div class="col-md-6">
                      <label>Source</label>
                      <div class="form-group">
                        <textarea
                          type="text"
                          id="source"
                          name="source"
                          class="form-control"
                          placeholder="lead Souve"
                          v-model="form.source"
                        ></textarea>

                        <template v-if="errors">
                          <span v-for="(fieldsError, fieldName) in errors" :key="fieldName">
                            <template v-if="fieldName == 'source'">
                              <p class="errors">
                                <strong>{{ fieldsError.join('\n') }}</strong>
                              </p>
                            </template>
                          </span>
                        </template>
                      </div>
                    </div>
                  </div>
                  <div class="row">
                    <div class="col-md-6">
                      <label>Value</label>
                      <div class="form-group">
                        <input
                          type="text"
                          id="value"
                          name="value"
                          class="form-control"
                          placeholder="lead Value"
                          v-model="form.value"
                        >

                        <template v-if="errors">
                          <span v-for="(fieldsError, fieldName) in errors" :key="fieldName">
                            <template v-if="fieldName == 'value'">
                              <p class="errors">
                                <strong>{{ fieldsError.join('\n') }}</strong>
                              </p>
                            </template>
                          </span>
                        </template>
                      </div>
                    </div>
                    <div class="col-md-6">
                      <label>Notes</label>
                      <div class="form-group">
                        <textarea
                          type="text"
                          id="notes"
                          name="notes"
                          class="form-control"
                          placeholder="lead Notes"
                          v-model="form.notes"
                        ></textarea>

                        <template v-if="errors">
                          <span v-for="(fieldsError, fieldName) in errors" :key="fieldName">
                            <template v-if="fieldName == 'notes'">
                              <p class="errors">
                                <strong>{{ fieldsError.join('\n') }}</strong>
                              </p>
                            </template>
                          </span>
                        </template>
                      </div>
                    </div>
                  </div>
                  <div class="row">
                    <div class="col-sm-6">
                      <div class="form-group">
                        <label for="exampleFormControlSelect1">Assigned To</label>
                        <template v-if="!userlist">
                          <select class="form-control" id="assigned_to">
                            <option value>No User Found</option>
                          </select>
                        </template>
                        <template v-else>
                          <select
                            v-model="form.assigned_to"
                            name="assigned_to"
                            class="form-control"
                            id="assigned_to"
                          >
                            <option value>Please Select</option>
                            <option v-for="user in userlist" :key="user.id" :value="user.id">
                              <template v-if="user.id == currentUser.id">Me</template>
                              <template v-else>{{ user.name }}</template>
                            </option>
                          </select>
                        </template>
                        <template v-if="errors">
                          <span v-for="(fieldsError, fieldName) in errors" :key="fieldName">
                            <template v-if="fieldName == 'assigned_to'">
                              <p class="errors">
                                <strong>{{ fieldsError.join('\n') }}</strong>
                              </p>
                            </template>
                          </span>
                        </template>
                      </div>
                    </div>
                    <div class="col-sm-6">
                      <div class="form-group">
                        <label>Close Date</label>
                        <div class="clearfix"></div>
                        <date-picker v-model="form.date" name="close_date"></date-picker>
                      </div>
                    </div>
                  </div>
                  <div class="row">
                    <div class="col-md-6">
                      <label>Email</label>
                      <div class="form-group">
                        <input
                          type="text"
                          id="email"
                          name="email"
                          class="form-control"
                          placeholder="User Email"
                          v-model="form.email"
                        >

                        <template v-if="errors">
                          <span v-for="(fieldsError, fieldName) in errors" :key="fieldName">
                            <template v-if="fieldName == 'email'">
                              <p class="errors">
                                <strong>{{ fieldsError.join('\n') }}</strong>
                              </p>
                            </template>
                          </span>
                        </template>
                      </div>
                    </div>
                    <div class="col-md-6">
                      <label>Phone</label>
                      <div class="form-group">
                        <input
                          type="text"
                          id="phone"
                          name="phone"
                          class="form-control"
                          placeholder="User Phone Number"
                          v-model="form.phone"
                        >

                        <template v-if="errors">
                          <span v-for="(fieldsError, fieldName) in errors" :key="fieldName">
                            <template v-if="fieldName == 'phone'">
                              <p class="errors">
                                <strong>{{ fieldsError.join('\n') }}</strong>
                              </p>
                            </template>
                          </span>
                        </template>
                      </div>
                    </div>
                  </div>
                </div>
                <div class="row">
                  <div class="col-md-6">
                    <div class="form-group">
                      <input
                        type="file"
                        multiple="multiple"
                        id="attachments"
                        @change="uploadFieldChange"
                      >
                      <hr>
                      <div class="col-md-12">
                        <div
                          class="attachment-holder animated fadeIn"
                          v-cloak
                          v-for="(attachment, index) in attachments"
                        >
                          <template v-if="attachment.file_name">
                            <span class="label label-primary">{{ attachment.file_name}}</span>
                          </template>
                          <template v-else>
                            <span
                              class="label label-primary"
                            >{{ attachment.name + ' (' + Number((attachment.size / 1024 / 1024).toFixed(1)) + 'MB)'}}</span>
                          </template>
                          <span
                            class
                            style="background: red; cursor: pointer;"
                            @click="removeAttachment(attachment)"
                          >
                            <button class="btn btn-xs btn-danger">Remove</button>
                          </span>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>

                <div class="row">
                  <div class="col-sm-6">
                    <div class="form-check">
                      <label>Status</label>
                      <br>
                      <label class="form-radio-label">
                        <input
                          class="form-radio-input"
                          v-model="form.status"
                          type="radio"
                          name="status"
                          value="open"
                          checked
                        >
                        <span class="form-radio-sign">Open</span>
                      </label>
                      <label class="form-radio-label ml-3">
                        <input
                          class="form-radio-input"
                          v-model="form.status"
                          type="radio"
                          name="status"
                          value="sent"
                        >
                        <span class="form-radio-sign">Proposal Sent</span>
                      </label>
                      <label class="form-radio-label ml-3">
                        <input
                          class="form-radio-input"
                          v-model="form.status"
                          type="radio"
                          name="status"
                          value="won"
                        >
                        <span class="form-radio-sign">Won</span>
                      </label>
                      <label class="form-radio-label ml-3">
                        <input
                          class="form-radio-input"
                          v-model="form.status"
                          type="radio"
                          name="status"
                          value="lost"
                        >
                        <span class="form-radio-sign">lost</span>
                      </label>
                    </div>
                  </div>
                </div>
                <div class="col-md-6">
                  <div class="form-group">
                    <button type="submit" class="btn btn-success">Save</button>
                    <button @click="clearForm()" class="btn btn-danger">Cancel</button>
                  </div>
                </div>
              </form>
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="container-fluid" style="background:#fff;">
      <kanban-board :stages="stages" :blocks="blocks" @update-block="updateBlock">
        <div v-for="stage in stages" :slot="stage">
          <h2>{{ stage }}</h2>
        </div>
        <div v-for="block in blocks" :slot="block.id">
          <div>
            <strong>{{ block.name }}</strong>
          </div>
          <p></p>
          <button class="btn btn-danger">UKDH</button>
          <button class="btn btn-warning">£ {{ block.value }}</button>
          <router-link :to="`/account/${block.id}/convert`" class="btn btn-primary">create account</router-link>
          <div class="text-right">
            <router-link :to="`/leads/${block.id}`" class="btn btn-link btn-info">
              <i class="la la-street-view"></i>
            </router-link>

            <a href="#" @click="deleteLead(block.id)" class="btn btn-link btn-danger">
              <i class="la la-times"></i>
            </a>
            <a href="#" @click="editLead(block)" class="btn btn-link btn-primary">
              <i class="la la-edit"></i>
            </a>
          </div>
        </div>
      </kanban-board>
    </div>
  </div>
</template>
<script>
import { addLeadsAPI } from "../../helpers/api";
import { updateStatus } from "../../helpers/api";
import { getCommonAPI } from "../../helpers/api";
import { deleteAPI } from "../../helpers/api";
import validate from "validate.js";
import DatePicker from "vue2-datepicker";

export default {
  name: "leads",
  components: {
    DatePicker
  },
  data() {
    return {
      leads: [],
      userlist: [],
      attachments: [],
      percentCompleted: 0,
      upload_size: 0,
      result: {},
      stages: ["open", "sent", "lost", "won"],
      blocks: [],
      form: {
        id: "",
        name: "",
        source: "",
        value: 0,
        notes: "",
        user_id: "",
        assigned_to: 1,
        date: new Date(),
        email: "",
        phone: "",
        status: ""
      },
      lead_id: "",
      pagination: {},
      edit: false,
      isOpen: 0,
      seen: true,
      errors: null
    };
  },
  created() {
    this.fetchLeads();
    this.getusers();
  },
  mounted() {
    this.$store.dispatch("leads");
  },
  methods: {
    getusers(page_url) {
      let vm = this;
      getCommonAPI("/users", "get", {
        headers: {
          Authorization: `Bearer ${this.currentUser.token}`,
          Accept: "application/json"
        }
      }).then(res => {
        vm.userlist = res.data;
      });
    },

    fetchLeads(page_url) {
      let vm = this;
      page_url = page_url || "/leads/lead";
      getCommonAPI(page_url, "get", {
        headers: {
          Authorization: `Bearer ${this.currentUser.token}`,
          Accept: "application/json"
        }
      }).then(res => {
        vm.blocks = res.data.data;
        //vm.makePagination(res.meta, res.links);
      });
    },
    makePagination(meta, links) {
      let pagination = {
        current_page: meta.current_page,
        last_page: meta.last_page,
        next_page_url: links.next,
        prev_page_url: links.prev
      };
      this.pagination = pagination;
    },
    editLead(form) {
      console.log(form);
      this.edit = true;
      this.seen = false;
      this.form.id = form.id;
      this.form.name = form.name;
      this.form.lead_sid = form.lead_sid;
      this.form.status = form.status;
      this.form.type = form.type;
      this.form.source = form.source;
      this.form.value = form.value;
      this.form.notes = form.notes;
      this.form.email = form.email;
      this.form.phone = form.phone;
      this.form.assigned_to = form.assigned_to;
      this.form.date = form.close_date;
      this.attachments = form.uploads;
    },
    clearForm() {
      this.edit = false;
      this.form.id = null;
      this.form.user_id = null;
      this.form.assigned_to = "";
      this.form.type = "";
      this.form.status = true;
      this.form.name = "";
      this.form.source = "";
      this.form.value = "";
      this.form.notes = "";
      this.form.email = "";
      this.form.phone = "";
      this.attachments = [];
    },
    addLeads() {
      if (this.edit === false) {
        // add new leads
        this.errors = null;
        const constraints = this.getConstraints();
        const errors = validate(this.$data.form, constraints);
        if (errors) {
          this.errors = errors;
          return;
        }
        // multiple file uploading
        this.lead = document.getElementById("leadform");
        const formData = new FormData(this.lead);
        if (this.attachments.length > 0) {
          for (var i = 0; i < this.attachments.length; i++) {
            let attachment = this.attachments[i];
            formData.append("attachments[]", attachment);
          }
        }
        var config = {
          headers: { "Content-Type": "multipart/form-data" },
          onUploadProgress: function(progressEvent) {
            this.percentCompleted = Math.round(
              (progressEvent.loaded * 100) / progressEvent.total
            );
            this.$forceUpdate();
          }.bind(this)
        };
        //end
        this.$store.dispatch("lead");

        addLeadsAPI(formData, "post").then(res => {
          swal("Good job!", "You clicked the button!", "success");
          this.clearForm();
          this.fetchLeads();
          //this.attachments = [];
        });
      } else {
        this.errors = null;

        const constraints = this.getConstraints();
        const errors = validate(this.$data.form, constraints);
        if (errors) {
          this.errors = errors;
          return;
        }
        console.log("i am in edit");
        // multiple file uploading
        this.lead = document.getElementById("leadform");
        let formData = new FormData(this.lead);
        if (this.attachments.length > 0) {
          for (var i = 0; i < this.attachments.length; i++) {
            let attachment = this.attachments[i];
            formData.append("attachments[]", attachment);
          }
        }
        console.log(formData);
        var config = {
          headers: { "Content-Type": "multipart/form-data" },
          onUploadProgress: function(progressEvent) {
            this.percentCompleted = Math.round(
              (progressEvent.loaded * 100) / progressEvent.total
            );
            this.$forceUpdate();
          }.bind(this)
        };
        //end
        console.log(formData);
        this.$store.dispatch("lead");
        //update
        addLeadsAPI(formData, "put").then(res => {
          swal("Good job!", "You clicked the button!", "success");
          this.clearForm();
          this.fetchLeads();
          //this.attachments = [];
        });
      }
    },
    getConstraints() {
      return {
        name: {
          presence: true,
          length: {
            minimum: 6,
            message: "Must be at least 6 characters long"
          }
        },
        source: {
          presence: true,
          length: {
            minimum: 6,
            message: "Must be at least 6 characters long"
          }
        },
        value: {
          presence: true,
          length: {
            minimum: 1,
            message: "Must be at least 1 characters long"
          }
        },
        notes: {
          presence: true,
          length: {
            minimum: 6,
            message: "Must be at least 6 characters long"
          }
        }
      };
    },
    updateBlock(id, status) {
      //api call axios
      updateStatus(id, status, "get").then(res => {
        this.clearForm();
        this.fetchLeads();
      });
      this.blocks.find(b => b.id === Number(id)).status = status;
    },
    deleteLead(id) {
      swal({
        title: "Are you sure?",
        text: "Do you really want to delete Lead!",
        type: "warning",
        buttons: {
          confirm: {
            text: "Yes, delete it!",
            className: "btn btn-success"
          },
          cancel: {
            visible: true,
            className: "btn btn-danger"
          }
        }
      }).then(Delete => {
        if (Delete) {
          deleteAPI(`/lead/${id}`, "delete", {
            headers: {
              Authorization: `Bearer ${this.currentUser.token}`,
              Accept: "application/json"
            }
          }).then(res => {
            swal({
              title: "Deleted!",
              text: "Your lead has been deleted.",
              type: "success",
              buttons: {
                confirm: {
                  className: "btn btn-success"
                }
              }
            });
            this.fetchLeads();
          });
        } else {
          this.fetchLeads();
          swal.close();
        }
      });
    },
    getAttachmentSize() {
      this.upload_size = 0; // Reset to beginningƒ
      this.attachments.map(item => {
        this.upload_size += parseInt(item.size);
      });

      this.upload_size = Number(this.upload_size.toFixed(1));
      this.$forceUpdate();
    },

    removeAttachment(attachment) {
      this.attachments.splice(this.attachments.indexOf(attachment), 1);

      this.getAttachmentSize();
    },
    // This function will be called every time you add a file
    uploadFieldChange(e) {
      console.log(this.attachments);
      var files = e.target.files || e.dataTransfer.files;
      if (!files.length) return;
      for (var i = files.length - 1; i >= 0; i--) {
        this.attachments.push(files[i]);
      }
      console.log("out");
      // Reset the form to avoid copying these files multiple times into this.attachments
      document.getElementById("attachments").value = [];
    }
  },
  computed: {
    users() {
      return this.$store.getters.users;
    },

    currentUser() {
      return this.$store.getters.currentUser;
    }
  }
};
</script>
<style lang="scss">
@import "../assets/board.scss";
</style>
<style scoped>
.vue-js-switch#changed-font {
  font-size: 30px;
}
.hide {
  display: none;
}
.errors {
  color: lightcoral;
  border-radius: 5px;
  padding: 21px 0 2px 0;
}
</style>

when edit option true. I am calling method addLeadsAPI for posting data with axios put but Formdata is empty $request->all().

Anyone can help me with this?seems axios put is not working for editing data. through formdata.

1

5 Answers 5

26

Laravel can not handle multipart-formdata well with PUT method. See Input from PUT requests sent as multipart/form-data is unavailable #13457.

If your code actually uses the PUT method, it seems to be affected by this problem.

There are several workarounds.

Dealing with the client side:

  • Instead of PUT method, use POST method with _method parameter value set to PUT (called 'method spoofing')

Dealing with the server side:

  • Add a package that performs multipart processing to Laravel. (ex. illuminatech/multipart-middleware)
  • Use pecl/apfd extension which provides ability to parse 'multipart/form-data' HTTP requests for any request method.
Sign up to request clarification or add additional context in comments.

1 Comment

Yes, I have fixed that by using post method instead of put.
9

I have changed the axioscall into post and set the value _method:put

addLeads() {
      if (this.edit === false) {
        // add new leads
        this.errors = null;
        const constraints = this.getConstraints();
        const errors = validate(this.$data.form, constraints);
        if (errors) {
          this.errors = errors;
          return;
        }
        // multiple file uploading
        this.lead = document.getElementById("leadform");
        const formData = new FormData(this.lead);
        if (this.attachments.length > 0) {
          for (var i = 0; i < this.attachments.length; i++) {
            let attachment = this.attachments[i];
            formData.append("attachments[]", attachment);
          }
        }
        var config = {
          headers: { "Content-Type": "multipart/form-data" },
          onUploadProgress: function(progressEvent) {
            this.percentCompleted = Math.round(
              (progressEvent.loaded * 100) / progressEvent.total
            );
            this.$forceUpdate();
          }.bind(this)
        };
        //end
        this.$store.dispatch("lead");
        formData.append("_method", "post");
        addLeadsAPI(formData, "post", config).then(res => {
          swal("Good job!", "You clicked the button!", "success");
          this.clearForm();
          this.fetchLeads();
          //this.attachments = [];
        });
      } else {
        this.errors = null;

        const constraints = this.getConstraints();
        const errors = validate(this.$data.form, constraints);
        if (errors) {
          this.errors = errors;
          return;
        }
        console.log("i am in edit");
        // multiple file uploading
        this.lead = document.getElementById("leadform");
        let formData = new FormData(this.lead);
        if (this.attachments.length > 0) {
          for (var i = 0; i < this.attachments.length; i++) {
            let attachment = this.attachments[i];
            formData.append("attachments[]", attachment);
          }
        }
        formData.append("_method", "put");
        formData.append("id", this.form.id);
        console.log(formData);
        var config = {
          headers: { "Content-Type": "application/x-www-form-urlencoded" },
          onUploadProgress: function(progressEvent) {
            this.percentCompleted = Math.round(
              (progressEvent.loaded * 100) / progressEvent.total
            );
            this.$forceUpdate();
          }.bind(this)
        };
        //end
        console.log(formData);
        this.$store.dispatch("lead");
        //update
        addLeadsAPI(formData, "put", config).then(res => {
          swal("Good job!", "You clicked the button!", "success");
          this.clearForm();
          this.fetchLeads();
          //this.attachments = [];
        });
      }
    },

Comments

7

Well, I had an issue trying to update records using axios & vue.js.

The solution is to set the method value on the formData to putand send the request using the post method. Something like this:

console.log("i am in edit");
    // multiple file uploading
    this.lead = document.getElementById("leadform");
    let formData = new FormData(this.lead);
    if (this.attachments.length > 0) {
      for (var i = 0; i < this.attachments.length; i++) {
        let attachment = this.attachments[i];
        formData.append("attachments[]", attachment);
      }
    }
    formData.append("_method", "put");
    console.log(formData);

In your axios request:

axios({
        method: "POST", // this is important
        url: {$your_destination_url},
        data: formData,
        headers: { "Content-Type": "multipart/form-data" }
    })
        .then(r => console.log(r.data))
        .catch(e => console.log(e));

Comments

0

It may be related to this, https://laravel.com/docs/5.0/routing#method-spoofing. when using PUT, PATCH or DELETE, you may need to also let laravel know the form method you are using. Try adding "_method" property with the value "PUT", and let me know if that works for you

Comments

0

My previous wrong code -

let data = new FormData()
data.append('message', 'AnyMessage')

Instead of FormData use the following String that works fine -

let data = "message=AnyMessage"

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.