0

I have a form that can contain from 1 to 5000 fields where these fields are sent via ajax and I need them to be sent every 10 fields, because serializing does not support this amount of request, how can I do this?

I'm using laravel 5.8

$('#botaosalvar').on('click', function(event) {
  event.preventDefault();
  var serializeDados = $('#formdados').serializeArray();
  console.log(serializeDados);

  $.ajax({
    type: 'POST',
    url: "{{ route('originalMap_edit') }}",
    data: serializeDados,
    dataType: 'json'
  }).done(function(res) {
    console.log(res);
  });
});
Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
  • 1
    You can easily chunk the array and loop through it: https://stackoverflow.com/q/11318680/519413. ***However*** sending that many AJAX requests isn't a good idea. I'd suggest you look for a way to cut down the amount of data you need to send, for example sending an AJAX request to save each field as it's updated, or having a method of knowing which fields have been changed so that only they get sent to the server instead of all 5000 – Rory McCrossan Jun 02 '21 at 16:38
  • 1
    @RoryMcCrossan I'd also add that I sincerely doubt 10 is the limit of fields for a POST. You'd need ***exceptionally*** large data for that to be the case. While request bodies might be limited, I'd expect a lot more than 10 values to be sent. – VLAZ Jun 02 '21 at 16:43
  • 1
    @RoryMcCrossan this helped me, i will split the matrices to send them, thank you – Lucas Steinbach Jun 02 '21 at 17:18

2 Answers2

0

As the commenters implied, the approach you're taking (executing hundreds of Ajax requests) isn't a good design. It will be fragile (imagine 20 out of 100 requests succeeding, and the other 80 failing... try doing data recovery from that!).

Instead, serialize all the data from the form into a single JSON object, and post that object all at once. Make sure you have GZIP compression on to minimize the bytes on the wire.

Alex Weinstein
  • 9,823
  • 9
  • 42
  • 59
0

If you decide you want to chunk your data and send it in multiple requests, which is not advised, consider this example.

$(function() {
  function sendData(url, data) {
    $.ajax({
      type: 'POST',
      url: url,
      data: data,
      dataType: 'json',
      success: function(res) {
        console.log(res);
      }
    });
  }

  function getDataPair(element) {
    if ($(element).is("textarea")) {
      return {
        name: $(element).attr("name"),
        value: $(element).text()
      };
    }
    return {
      name: $(element).attr("name"),
      value: $(element).val()
    };
  }

  function formSubmit(form, chunk) {
    var elements = $("input, textarea, select", form);
    if (chunk == undefined) {
      chunk = 10;
    }
    var myData = [];
    elements.each(function(index, el) {
      if (myData.length == chunk) {
        sendData("{{ route('originalMap_edit') }}", myData);
        myData = [];
      }
      myData.push(getDataPair(el));
      console.log(index, myData);
    });
  }

  $('#botaosalvar').on('click', function(event) {
    event.preventDefault();
    formSubmit($('#formdados'), 10);
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="formdados">
  <div><input type="text" name="a" value="1" id="a"></div>
  <div><input type="text" name="b" value="2" id="b"></div>
  <div><input type="hidden" name="c" value="3" id="c"></div>
  <div>
    <textarea name="d" rows="2" cols="40">4</textarea>
  </div>
  <div>
    <select name="e">
      <option value="5" selected="selected">5</option>
      <option value="6">6</option>
      <option value="7">7</option>
    </select>
  </div>
  <div>
    <input type="checkbox" name="f" value="8" id="f"> <label for="f">8</label>
  </div>
  <div><input type="text" name="g" value="9" id="g"></div>
  <div><input type="text" name="h" value="10" id="h"></div>
  <div><input type="hidden" name="i" value="11" id="i"></div>
  <div>
    <textarea name="j" rows="2" cols="40">12</textarea>
  </div>
  <div>
    <select name="k">
      <option value="13" selected="selected">13</option>
      <option value="14">14</option>
      <option value="15">15</option>
    </select>
  </div>
  <div>
    <input type="checkbox" name="l" value="16" id="l"> <label for="l">16</label>
  </div>
  <div>
    <button type="submit" id="botaosalvar">Submit</button>
  </div>
</form>

As was discussed, this has a lot of pitfalls. If you have 5000 fields, this will take a bunch of time iterating over all the items and will send about 500 POSTs to your server, back to back.

  1. Your POST handler will have to put all the data back together
  2. If any of these Fail, there may be missing data
  3. If the script halts or does not complete, you will have orphaned or lost data
  4. The number of concurrent connections might be more than your web server can handle, it may QUEUE or DROP the requests (Similar to a DOS attack)

It would be advisable to not separate the data. It might look like this:

$(function() {
  function sendData(url, data) {
    $.ajax({
      type: 'POST',
      url: url,
      data: data,
      dataType: 'json',
      success: function(res) {
        console.log(res);
      }
    });
  }

  function getDataPair(element) {
    if ($(element).is("textarea")) {
      return {
        name: $(element).attr("name"),
        value: $(element).text()
      };
    }
    return {
      name: $(element).attr("name"),
      value: $(element).val()
    };
  }

  function formSubmit(form) {
    var elements = $("input, textarea, select", form);
    var myData = [];
    elements.each(function(index, el) {
      myData.push(getDataPair(el));
    });
    sendData("{{ route('originalMap_edit') }}", myData);
  }

  $('#botaosalvar').on('click', function(event) {
    event.preventDefault();
    formSubmit($('#formdados'));
  });
});
Twisty
  • 30,304
  • 2
  • 26
  • 45