0

I have this Object

{
  "Data1": 1,
  "Data2": "some string",
  "Data3": [
    {
      "ID": 0,
      "Name": "some name",
      "SomeArray": []
    },
    {
     "ID": 0,
     "Name": "another name",
     "SomeArray": [
       "DataA": 0,
       "DataB": "some data again"
     ]
    }],
  "Data4": "some string again"
}

The model which it will receive in the controller is this:

public class Data 
{
   public int Data1 { get; set; }
   public string Data2 { get; set; }
   public List<AnotherClass> Data3 { get; set; }
   public string Data4 { get; set; }
}

public class AnotherClass
{
   public int ID { get; set; }
   public string Name { get; set; }
   public List<DataList> SomeArray { get; set; }
}

public class DataList
{
   public int DataA { get; set; }
   public string DataB { get; set; }
}

The data that is to be set in Data3 is coming from a table where new inputs are retrieved from a modal popup and populated in the table. SomeArray data is coming from a dropdown which uses Select2 tool to set multiple choices in a dropdown.

The idea is that once the user clicks "Save", it will get all of the data, including those in the table and form this JSON object. From this object, I want to convert it into a FormData. However when it iterates into Data3, it doesn't convert it into an array of objects even if I stringify it. I've also tried this one Convert JS Object to form data but was unsuccessful.

Here's what I did so far:

var details = GetDetails(); // This contains `Data1`, `Data2` and `Data4`
var data3 = GetData3FromTable(); // This contains the list of `Data3`

var result = new FormData();
for (var key in details) {
   result.append(key, details[key]);
}

result.append("Data3", JSON.stringify(data3));
result.append("UploadFile", $("#upload")[0].files[0]);

// do ajax put or post after this line

Is there any jquery or javascript plugin that I can use to convert this object into FormData? Or is there any other way to convert it into FormData?

Musikero31
  • 3,115
  • 6
  • 39
  • 60
  • How would the form look that produced such formdata? Also why not just send it as JSON, that is what the string format is for – mplungjan Nov 16 '20 at 18:33
  • This is just a section of the entire JSON object and data from Data3 is coming from a table. The reason why I am converting this object to FormData is because I will be adding a file uploader control here. – Musikero31 Nov 17 '20 at 00:56

2 Answers2

0

You can send deeply nested data in HTML forms, but I have noticed that different web servers may interpret the more complex structures differently, so you may need to check your framework/app's middleware to ensure proper decoding. You may find it easier to read values into Javascript and send the data from there.

Your Data3 object could be represented using something like this:

<input type="text" name="data[Data3][0][id]" value="0">
<input type="text" name="data[Data3][0][Name]" value="some name">
<input type="text" name="data[Data3][0][SomeArray][]" value="">

You need a "parent" field (data in this example) which houses the child elements.

Note that you have to be careful of any [] -- you may need to specify the array index manually as above, otherwise the "grouping" of values won't be respected.

Also beware of names ending with []: those fields will still send values, even if it's an empty string, so you may need to filter those out.

Everett
  • 8,746
  • 5
  • 35
  • 49
  • The story of `Data3` is that this is coming from a table. What I did was that once I got the data from that table, I set it in `Data3` like so. – Musikero31 Nov 17 '20 at 02:49
  • If this is coming from a database table, then you may want to consider using the primary key as the array index. E.g. `data[Data3][123][Name]` for row 123. – Everett Nov 17 '20 at 03:45
  • Then how to cater for the new ones? Also the data entry for the new entries will be coming from a modal popup (all of them are dropdowns) and populated in the table. Then the `SomeArray` is using a `Select2` plugin. So I don't know how it fits in my issue. – Musikero31 Nov 17 '20 at 03:55
  • If you need to code a form for a new record, I would keep the structure "shallow", e.g. use `` and post that to an API route dedicated to creating new resources, e.g. `/api/users` -- there is seldom a need to post all the old data when creating a new resource, but if you have that need, perhaps you can elaborate more in your question to help us understand what you are needing to do. – Everett Nov 17 '20 at 04:24
0

I found this link object-to-form-data where it converts any object, including nested arrays and upload files into FormData. However, there's just one change that needs to be done:

From the link, replace objectToFormData(obj[property], fd, property); with objectToFormData(obj[property], fd, formKey);. This way, it sets the original property as the key. The output of the FormData when it is passed to the controller will be this:

Data1: 1
Data2: some string
Data3[0][ID]: 0
Data3[0][Name]: some name
Data3[0][SomeArray]: []
Data3[1][ID]: 0
Data3[1][Name]: another name
Data3[1][SomeArray][0][DataA]: 0
Data3[1][SomeArray][0][DataB]: some data again
Data4: some string again

I hope this helps others!

Musikero31
  • 3,115
  • 6
  • 39
  • 60