1

I am having a problem uploading an image from a from a form in a vue file. I tried several ways to do this but it seems the file is not properly being set.

  • I have set "enctype="multipart/form-data" in my form tag

  • Here is my input element:

    <input @change="onFileChange" type="file" accept="image/*" class="form-control" name="file" id="file" aria-describedby="helpId" placeholder="Upload a file" />

  • Here is my data objetcs and methods that send the data:

      data() {
          return {
        editMode: false,
        professionaldevelopmentitems: [],
        professionaldevelopmentitem: {
          domain: 1,
          domaincategory: 1,
          title: "",
          dateofpd: "",
          location: "",
          lengthofpd: "",
          facilitatorname: "",
          facilitatorcredentials: "",
          reflection: "",
          file: "",
        },
      };
    },
    methods: {
      onFileChange(e) {
        alert(e.target.files[0]);
        alert(e.target.files[0].name);
        var files = e.target.files || e.dataTransfer.files;
        if (!files.length)
          return;
        this.professionaldevelopmentitem.file = e.target.files[0];
        alert(this.professionaldevelopmentitem.file);
      },    
      async addProfessionalDevelopmentItem() {
        document.getElementById("pdForm").reset();
        this.editMode = false;
        const res = await axios.post(
          "/api/professionaldevelopmentitems",
          this.professionaldevelopmentitem
        );
    
        if (res.status === 201) {
          Toast.fire({
            icon: "success",
            title: res.data,
          });
          document.getElementById("pdForm").reset();
          $("#manageProfessionalDevelopmentItem").modal("hide");
          Fire.$emit("modifiedPDItem");
        }
      },
      async editProfessionalDevelopmentItem(data) {
        this.professionaldevelopmentitem = Object.assign({}, data);
        this.editMode = true;
      },
      async updateProfessionalDevelopmentItems(data) {
        const res = await axios.put(
          `/api/professionaldevelopmentitems/${data.id}`,
          this.professionaldevelopmentitem
        );
    
        if (res.status === 200) {
          Toast.fire({
            icon: "success",
            title: res.data,
          });
          document.getElementById("pdForm").reset();
          $("#manageProfessionalDevelopmentItem").modal("hide");
          Fire.$emit("modifiedPDItem");
          this.editMode = false;
        }
      },
    

I receive data in my controller and try to store the file:

public function update(Request $request, $id) {

dd($request->all());

$this->validate($request, [
    'title' => ['required'],
    'dateofpd' => ['required'],
    'lengthofpd' => ['required'],
    'location' => ['required']
]);

$path = $request->file('filename')->store('uploads');

$pditem = ProfessionalDevelopmentItem::find($id);
$pditem->domain = $request->domain;
$pditem->domaincategory = $request->domaincategory;
$pditem->title = $request->title;
$pditem->dateofpd = $request->dateofpd;
$pditem->lengthofpd = $request->lengthofpd;
$pditem->location = $request->location;
$pditem->facilitatorname = $request->facilitatorname;
$pditem->facilitatorcredentials = $request->facilitatorcredentials;
$pditem->certificategranted = $request->certificategranted;
$pditem->certificateexpires = $request->certificateexpires;
$pditem->certificateexpiration = $request->certificateexpiration;
$pditem->reflection = $request->reflection;
$pditem->nameofinstitution = $request->nameofinstitution;
$pditem->coursename = $request->coursename;
$pditem->coursecode = $request->coursecode;
$pditem->hoursofinstruction = $request->hoursofinstruction;
$pditem->creditgranted = $request->creditgranted;
$pditem->bookname = $request->bookname;
$pditem->bookauthor = $request->bookauthor;
$pditem->bookyear = $request->bookyear;
$pditem->bookpublisher = $request->bookpublisher;
$pditem->otherdescription = $request->otherdescription;
$pditem->filename = $path;

$pditem->save();

return response('Successfully Updated the Professional Development Item.', 200);

}

the response back is an error on the line when it tries to store the file:

"message": "Call to a member function store() on array",
"exception": "Error",

Any thoughts on what I am dong wrong would be appreciated.

11
  • 2
    shouldn't it be $path = $request->file('filename')->store('uploads'); Commented Dec 11, 2020 at 18:19
  • Thanks, I just added that - it did not make a difference. Commented Dec 11, 2020 at 18:21
  • 1
    try to check whats inside $request->file('filename') using dd($request->file('filename')); Commented Dec 11, 2020 at 18:23
  • 1
    you are running the wrong dd, either try to run the whole request using dd($request) or use $request->file('filename'), also check dd($request->hasFile('filename')) returns true of false Commented Dec 11, 2020 at 19:00
  • 1
    I think based on your Vue component code the file should be available under "file" key. Try dd($request->hasFile('file')) Commented Dec 11, 2020 at 19:20

2 Answers 2

1

Try sending the uploaded file within FormData. Define a method in the Vue component to prepare the FormData with all data you want to send via ajax to the server

prepareFormData() {
    let data = new FormData;

    Object.keys(this.professionaldevelopmentitem).forEach(
        key => data.append(key, this.professionaldevelopmentitem[key]
    );

    return data;
}

Then use this method to get the FormData and send it as data to the server in addProfessionalDeveloomentItem and updataProfessionalDevelopmentItems

async addProfessionalDevelopmentItem() {
    document.getElementById("pdForm").reset();
    this.editMode = false;
    const res = await axios.post(
      "/api/professionaldevelopmentitems",
      this.prepareFormData()
    );

    if (res.status === 201) {
      Toast.fire({
        icon: "success",
        title: res.data,
      });
      document.getElementById("pdForm").reset();
      $("#manageProfessionalDevelopmentItem").modal("hide");
      Fire.$emit("modifiedPDItem");
    }
  },
  

  async updateProfessionalDevelopmentItems(data) {
    const res = await axios.put(
      `/api/professionaldevelopmentitems/${data.id}`,
      this.prepareFormData()
    );

    if (res.status === 200) {
      Toast.fire({
        icon: "success",
        title: res.data,
      });
      document.getElementById("pdForm").reset();
      $("#manageProfessionalDevelopmentItem").modal("hide");
      Fire.$emit("modifiedPDItem");
      this.editMode = false;
    }
}

Then you should get the uploaded file in the $request under key file $request->file('file')

Sign up to request clarification or add additional context in comments.

Comments

0

This error means that $request->file('filename') returns array. In our case it's because we allowed users to submit 2 files at once:

<form action="/upload" method="post" enctype="multipart/form-data">
    @csrf
    <input type="file" name="filename[]"><br>
    <input type="file" name="filename[]"><br>
    <input type="submit">
</form>

To fix this in Laravel 9 we added the type check of the variable in the controller's method:

public function upload(Request $request)
{
    $file = $request->file('filename');

    if (is_array($file)) {
        foreach ($file as $item) {
            $item->store('uploads');
        }
    } else {
        $file->store('uploads');
    }

    // ...
}

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.