0

How can I send a Form like this using Fetch API to a laravel endpoint: The problem I have is that I can't get the file and inputs with the array name "[]" at the same time. I tried to loop through each element of the form and create a json object but when there is a file input in the form it makes it fail because you must send the data as application/json format which you have to JSON.stringyfy(data) which causes the file input to disapear.
I also tried using FormData() which is working perfectly fine with files and other normal inputs but when it comes to the inputs with array name name[] or event price[10] or `price[1][], It doesnt work. What is the best approach to send this kind of form?

<form action="/end-point">

    <input type="text" name="title" value="my article title">
    <textarea name="body" id="" cols="30" rows="10">THis is the body</textarea>
    
    <input type="checkbox" name="facilities[]" value="1">
    <input type="checkbox" name="facilities[]" value="2">
    
    <input type="radio" name="option[]" value="3">
    <input type="radio" name="option[]" value="4">
    
    <input type="text" name="name[]" value="test1">
    <input type="text" name="name[]" value="test2">

    <select name="service_id[]">
        <option value="1">Service1</option>
        <option value="2">Service2</option>
    </select>

    <select name="service_id[]">
        <option value="1">Service1</option>
        <option value="2">Service2</option>
    </select>

    <select name="service_id[]">
        <option value="1">Service1</option>
        <option value="2">Service2</option>
    </select>
    
    <input type="file" name="picture">
    
</form>

THe Format I need in the laravel endpoint
[
"title" => "my article title"
  "body" => "THis is the body"
  "facilities" => array:2 [▼
    0 => "1"
    1 => "2"
  ]
  "option" => array:1 [▼
    0 => "3"
  ]
  "name" => array:2 [▼
    0 => "test1"
    1 => "test2"
  ]
  "service_id" => array:3 [▼
    0 => "1"
    1 => "1"
    2 => "1"
  ]
  "picture" => Illuminate\Http\UploadedFile {#244 ▼
    -test: false
    -originalName: "m16.jpg"
    -mimeType: "image/jpeg"
    -error: 0
    #hashName: null
    path: "C:\wamp64\tmp"
    filename: "php87C8.tmp"
    basename: "php87C8.tmp"
    pathname: "C:\wamp64\tmp\php87C8.tmp"
    extension: "tmp"
    realPath: "C:\wamp64\tmp\php87C8.tmp"
    aTime: 2020-07-02 04:41:33
    mTime: 2020-07-02 04:41:33
    cTime: 2020-07-02 04:41:33
    inode: 3096224744035967
    size: 25467
    perms: 0100666
    owner: 0
    group: 0
    type: "file"
    writable: true
    readable: true
    executable: false
    file: true
    dir: false
    link: false
    linkTarget: "C:\wamp64\tmp\php87C8.tmp"
  }
]
VeRJiL
  • 415
  • 4
  • 13
  • To upload a file, you should be sending a `multipart/form-data` request payload. – Phil Jul 01 '20 at 04:25
  • Without knowing **exactly** what format your Laravel backend expects, this is very difficult to answer. Please see the linked duplicate for some general information about uploading both files and data – Phil Jul 01 '20 at 04:27
  • @Phil The file is not the problem and I can all form data and the file using new FormData() but the problem happens when there are inputs with array name like – VeRJiL Jul 01 '20 at 13:28
  • @Phil You should not have closed my question non of the solutions out there are working in my scenario. I have been researching and developing all the possible ways which developers give but non works. – VeRJiL Jul 01 '20 at 13:30
  • Put simply, you cannot embed a file upload like that within JSON. The answers in the duplicate should have explained that – Phil Jul 02 '20 at 04:47

1 Answers1

-1

I'm using Vue on this to pass the file.

<input type="file" @change="onChange" class="mb-5">

On my methods

onChange(e) {
      this.form.image = e.target.files[0]
    }

This will return the image name

then in my POST ajax request is this method

  let form = new FormData()

  form.append('image', this.form.image)
  form.append('name', this.form.name) // [edited]

  fetch([url], {
    method: 'POST',
    Accept: "application/json",
    body: json.stringify(form)
  })
  .then(response => response.json())
  .then(image => console.log(image))

if this doesn't work try to change the Accept Header.

EDIT:

You will also pass the name or other field in the append.

EDIT 2

  let form = new FormData()[];

  foreach(form in forms) {
    form.append('image', this.form.image)
    form.append('name', this.form.name)
  }
  
  fetch([url], {
    method: 'POST',
    Accept: "application/json",
    body: json.stringify(form)
  })
  .then(response => response.json())
  .then(image => console.log(image))
Japs
  • 977
  • 2
  • 10
  • 19
  • You are sending only a file, and this is problem when we add some inputs with array name to the form like – VeRJiL Jun 22 '20 at 11:05
  • @VeRJiL you can now check the code. I edited it – Japs Jun 26 '20 at 05:25
  • thanks but this doesnt apply, because I am trying to get all the inputs as an array not a signle input – VeRJiL Jun 30 '20 at 10:41
  • I tried to edit again my answer but I don't think it will work just try another work around if it doesn't do any. – Japs Jul 02 '20 at 07:04