John Cadac
John Cadac

Reputation: 99

Ajax post sending nested array, undefined

I'm using var form = $("#AAAForm").serializeArray() to serialize all values from AAAForm. I then push all values from the cart to the form using the following code:

var CartPush = [{name: "OrderDetails", value: Cart}]
form.push(CartPush);

I then use the following Ajax function to send a post request to the server.

$.ajax({
            type: "POST",
            url: "/Update/Inventory",
            data: form,
            success: function (data) {
                alert(data); // show response
            }
        });

I expect it to send the following: (this is the output from console.log(form))

0: {name: "FirstName", value: "a"}
1: {name: "LastName", value: "a"}
2: {name: "PostalCode", value: "a"}
3: {name: "HouseNumber", value: "a"}
4: {name: "Street", value: "a"}
5: {name: "City", value: "a"}
6: {name: "State", value: "a"}
7: {name: "Country", value: "a"}
8: {name: "Email", value: "a"}
9: Array(1)
   0:
      name: "OrderDetails"
      value: Array(3)
         0: {ProductId: "760", Name: "Test ", ImageUrl: "258", Price: "0.10", Grade: "Rare", …}
         1: {ProductId: "873", Name: "Test2 ", ImageUrl: "371", Price: "0.20", Grade: "Holo", …}
         2: {ProductId: "744", Name: "Test3 ", ImageUrl: "242", Price: "0.35", Grade: "Rare", …}

However, the following is actually send to the server:

FirstName: a
LastName: a
PostalCode: a
HouseNumber: a
Street: a
City: a
State: a
Country: a
Email: a
undefined: 

Why is the Array I'm adding added as undefined? Also, how do I solve it? I created the following JSFiddle, witht the sample data. https://jsfiddle.net/s03uLvpy/

I don't think this is the issue, but for the complete picture. I'm Posting the data to the following function in dotnet core, I receive the form data just fine, however, the data I receive for OrderDetails is just empty, I think because the posted data is undefined.

 [HttpPost]
 public async Task<IActionResult> AccountAndAddress(OrderViewModel values, List<ProductsShopCartViewModel> OrderDetails)
        {
        return Ok();
        }

Upvotes: 0

Views: 1445

Answers (1)

Shyju
Shyju

Reputation: 218852

For model binding to work, the structure of the data you are sending should match with your action method parameter.

You have not shared how your server side view model classes looks like. Anyway, to handle a situation like this, I would create a single view model which has your 2 classes as properties

public class AccountAndAddressVm
{
    public List<AddressVm> Address { set; get; }
    public List<ProductsShopCartViewModel> OrderDetails { set; get; }
}
public class AddressVm
{
    public string Name { set; get; }
    public string Value { set; get; }
}
public class ProductsShopCartViewModel
{
    public int ProductId { set; get; }
    public string Name { set; get; }
    public int Quantity { set; get; }
}

and use this new AccountAndAddressVm class as the parameter of my action method, while using FromBody attribute decorator along with it. The FromBody attribute tells the model binder to read the data from the request body and map use it for model binding(mapping to this parameter).

[HttpPost]
public ActionResult AccountAndAddress([FromBody] AccountAndAddressVm OrderDetails)
{
    // Here I am simply returning what we received fore debugging.
    return Ok(OrderDetails );
}

Now all we have to do is send a JS object with same structure.

var form = [{ name: "FirstName", value: "Shyju" },
            { name: "PostalCode", value: "98052" },
            { name: "City", value: "Redmond" }];


var cart = [{ "ProductId": "760", "Name": "Test ",Amount": 1 },
            { "ProductId": "360", "Name": "Xox ",Amount": 4 }
           ];

var d = { Address: form, OrderDetails: cart };
// the "d" object has similar structure like our AccountAndAddressVm class

$.ajax({
         type: "POST",
         url: "/Home/AccountAndAddress",
         data: JSON.stringify(d),
         contentType:"application/json",
         success: function (data) {
               console.log('response',data);
         }
});

The JSON.stringify method will convert the JavaScript object and creates a string representation of that. The contentType:"application/json" property will tell jQuery to send the application/json as the Content-Type request header.

Upvotes: 1

Related Questions