Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I have a form and I am using Ajax to submit data to the API. The form contains a repeater which aids the user to enter any number of data repeatedly. The user submits the form after a few steps. When I try to bind the value to the Object is not binding. The API is built using Spring Boot, and by default, Jackson is used for conversion of JSON to Objects.

Here is the full code,

f.submit(function(e){
            e.preventDefault();
            var ignoreFields = ["_csrf"];
            var unindexed_array = $(this).serializeArray().filter(val => ignoreFields.indexOf(val.name) === -1);
            var indexed_array = {};
            $.map(unindexed_array, function(n, i){
                indexed_array[n['name']] = n['value'];
            });
            $.ajax({
                  type: $(this).attr('method'), 
                  contentType: 'application/json',
                  url: $(this).attr('action'), 
                  data: JSON.stringify(indexed_array),
                  dataType: 'json', cache: false, timeout: 600000,
                  success: function (d) {
                  }, error: function (e) {
                  }
              });
        })

before JSON.stringify()

   {
    act1[0].quantity: "4",
    act1[0].name: "abc",
    act1[0].status: "Working",
    act2[0].quantity: "5",
    act2[0].id: "1",
    act3[0].quantity: "4",
    act3[0].id: "2",
    act3[0].unit: "mm",
    activity: "zdzdsd zsdsad",
    endTime: "23:02",
    location: "sdasd",
    note: "sdfsdfsd sdfsdfsd",
    startTime: "03:03"
  }

if I convert the above code to the following format I expect this to work, since I am using a list and Jackson Library will be able to identify this format

    {
    endTime: "23:02",
    location: "sdasd",
    note: "sdfsdfsd sdfsdfsd",
    startTime: "03:03",
    act1:[{
       quantity: "4",
       name: "abc",
       status: "Working"
    }],
    act2:[{
       quantity: "5"
       id: "1"
    }],
    act3:[{
       quantity: "4"
       id: "2",
       unit: "mm"
    }]
}

I tried many ways in Javascript to convert into this format, How can we achieve the above format?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
187 views
Welcome To Ask or Share your Answers For Others

1 Answer

Keeping a personal library of helpful functions can often make this sort of transformation easier. I have used functions like the included assocPath, and hydrate many times, including in a recent SO answer (which has more details about what they do.)

Put together my solution involves a number of fairly small functions. I do have to make an assumption about your input structure not entirely clear from the question, namely that what's displayed is some kind of shorthand for a real JS format. If not, most of the code will probably still work; it just might take some additional effort to convert to something usable.

This is what it looks like:

// utility functions
const assoc = (prop, val, obj) => 
  Number .isInteger (prop) && Array .isArray (obj)
    ? [... obj .slice (0, prop), val, ...obj .slice (prop + 1)]
    : {...obj, [prop]: val}

const assocPath = ([p = undefined, ...ps], val, obj) => 
  p == undefined
    ? obj
    : ps.length == 0
      ? assoc(p, val, obj)
      : assoc(p, assocPath(ps, val, obj[p] || (obj[p] = Number .isInteger (ps[0]) ? [] : {})), obj)

const hydrate = (pvEntries) =>
  pvEntries .reduce ((a, [k, v]) => assocPath (k, v, a), {})


// helper functions
const extractIndices = s => 
  s .split (/[[]]/)
    .map (s => /^d+$/ .test (s) ? Number(s) : s)
    .filter(n => n !== '')

const makePath = (s) => 
  s .split ('.') .flatMap (extractIndices)


// main function
const transform = (input) =>
  hydrate (
    Object .entries (input)
      .map (([k, v]) => [makePath (k), v])
  )


// test data
const input = {"act1[0].quantity": "4", "act1[0].name": "abc", "act1[0].status": "Working", "act2[0].quantity": "5", "act2[0].id": "1", "act3[0].quantity": "4", "act3[0].id": "2", "act3[0].unit": "mm", "activity": "zdzdsd zsdsad", "endTime": "23:02", "location": "sdasd", "note": "sdfsdfsd sdfsdfsd", "startTime": "03:03"}


// demo
console .log (transform (input))
.as-console-wrapper {max-height: 100% !important; top: 0}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...