Ajax javascript Map to Spring controller - javascript

I am trying ajax Javascript Map, to spring controller. but it's getting null in backend. Please excuse if i am repeating question.
I can't change Map type, as my whole front end logic on it. Because set, get and has method from Map is what I need.
var ansMap = new Map(); // This way i created object
// added many values in ansMap,
$.ajax({
type: "POST",
url: myUrl,
contentType : 'application/json',
//cache: false,
dataType : 'json',
data : ansMap, // can't JSON.stringy(ansMap) as it gives empty json
success: function(result) {
console.log(result);
},
Spring code
#RequestMapping (value="myUrl", method=RequestMethod.POST)
public #ResponseBody String saveData(#RequestParam(required = false, value = "mapData") Map<String,List<String>> mapData, Model map)
{
log.info("Call Success");
log.info("mapData: "+mapData);
Please suggest what needs to be done here.

You can actually send your Map without mutating the value
var ansMap = new Map(); // This way i created object
// added many values in ansMap,
$.ajax({
type: "POST",
url: myUrl,
contentType : 'application/json',
//cache: false,
dataType : 'json',
data : JSON.stringify(Object.fromEntries(ansMap)), // can't JSON.stringy(ansMap) as it gives empty json
success: function(result) {
console.log(result);
},
That will turn it into a javascript object.
Object.fromEntries Will turn you Map into a javascript object, without altering the original Map
Regarding your backend i think you mis-interpret the #RequestParam annotation
The #RequestParam is to extract query parameters, form parameters and even files from the request.
I think that what you are looking for is #RequestBody.
Meaning you would be looking for something similar to :
#RequestMapping(value="/myUrl",method = RequestMethod.POST)
public String saveData( #RequestBody Map<String,Object> body) {

This should work
page
<button id="doPost"> post </button>
<script>
$(function () {
var map = new Map();
map.set('CIQ_2','aa');
map.set('CIQ_3','78965412300');
console.log(map);
$("#doPost").click (function() {
var settings = {
beforeSend: function(xhr, options) {
xhr.setRequestHeader("content-type" ,"application/json; charset=utf-8");
},
type: 'POST',
url: '/post' ,
data: JSON.stringify(Object.fromEntries(map))
}
$.ajax(settings).done(function(result) {
console.log("done : " + result);
});
});
});
</script>
Controller
#PostMapping("/post")
#ResponseBody
public String post(#RequestBody Map<String,String> data) {
System.out.println(data);
return "data well received";
}
will print
{CIQ_2=aa, CIQ_3=78965412300}
working code on GitHub

Related

Map list of objects from client to server

I would like to map a list of objects from client to server, using MVC. On the server I see that list is populated with correct number of items, but properties are empty. What am I doing wrong?
Here is the code from client:
var listCAORAS = [];
$('span.chkDelete input[type=checkbox]:checked').each(function (i, obj) {
var iORAS_KEY = $(obj).parent().attr('data-ioras_key');
if (iORAS_KEY) {
listCAORAS.push({ "iORAS_KEY": Number(iORAS_KEY) });
}
});
$.ajax({
method: 'post',
url: '/OrderSupplier/DeleteCAORAS/',
data: {
listCAORAS: listCAORAS
}
});
Server side:
public JsonResult DeleteCAORAS(List<DTO_CAORAS> listCAORAS)
{
}
public class DTO_CAORAS
{
public int? iORAS_KEY { get; set; }
//many more properties here
}
The default jQuery ajax contentType is 'application/x-www-form-urlencoded; charset=UTF-8' which means in order to bind to you model, the format of your data would need to be
$.ajax({
....
data: { [0].iORAS_KEY: 1, [1].iORAS_KEY: 1, [2].iORAS_KEY: 1, ... }
});
i.e your object names need to have zero-based, consecutive collection indexers.
Note that if your view is correctly generated (i.e. your checkboxes are bound to a bool property and you have a hidden input for the iORAS_KEY property), then all you would need is
$.ajax({
....
data $(yourForm).serialize()
});
To send an array of complex objects as you are doing, you must set the contentType to 'json' and stringify the data which instructs the DefaultModelBinder to use the JsonValueProviderFactory to deserialize the data to your model.
$.ajax({
url: '#Url.Action("DeleteCAORAS", "OrderSupplier")', // always use Url.Action() to generate the url
....
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({ listCAORAS: listCAORAS })
});

JSON Object always return undefined with AJAX

The JSON Object always return undefined in spite of the object contains data, i check it by using breakpoints in debugging
This is Action method in Controller:
public JsonResult GetMoreComments(int CommsCount, int ArticleID)
{
List<ComViewModel> comms = articleService.GetMoreComments(ArticleID, CommsCount);
return Json( comms );
}
and I also replaced the code in Action method to simple code like that but not work too:
public JsonResult GetMoreComments(int CommsCount, int ArticleID)
{
ComViewModel com = new ComViewModel
{
CommentContent = "cooooooooooontent",
CommentID = 99,
SpamCount = 22
};
return Json( com );
}
This is jQuery code for AJAX:
function GetMoreComments() {
$.ajax({
type: 'GET',
data: { CommsCount: #Model.Comments.Count, ArticleID: #Model.ArticleID },
url: '#Url.Action("GetMoreComments", "Comment")',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (result) {
var JsonParseData = JSON.parse(result);
alert(JsonParseData[0].CommentID)
alert(result[0].CommentID);
alert(result[0]["CommentID"]);
}
});
}
Usually you would have to parse your data if you need to alert it the way you have it. alert(result) should show data. If you need to access array of objects you must parse it first. Here is my example....
jQuery.post(ajaxurl, data, function(response) {
alert('Got this from the server: ' + response);
//PARSE data if you need to access objects
var resultstring = response.replace(',]',']');
var JsonParseData = JSON.parse(resultstring);
alert(JsonParseData[0].address)
});
That is wordpress ajax but its the same concept

javascript ajax call not not hitting controller

I am trying to build up a list of mock files for Dropzone.js to consume. I have an MVC controller method defined as follows:
[HttpPost]
public async Task<JsonResult> GetImageInfo(int imageId)
{
//int imgId;
//int.TryParse(imageId, out imgId);
var image = await RepublikDb.PropertyImage.FindAsync(imageId);
var path = Server.MapPath(image.ImageURI);
var size = new FileInfo(path).Length;
var fileName = new FileInfo(path).Name;
var thumbnailURI = image.ThumbnailImage.ImageURI.TrimStart('~');
return Json(new { fileName = fileName, size = size, thumbnailURI = thumbnailURI });
}
I have tested this endpoint with Postman, and everything works as expected, however each time I try and get the data in JS, the server returns a 500 error code, with complaints of the following: Exception Details: System.ArgumentException: The parameters dictionary contains a null entry for parameter 'imageId' of non-nullable type 'System.Int32'
Here is the JS AJAX code:
//Entry point to JS from razor. A comma separated string is passed here. Eg. imageIds = "10,12,14,16"
EditFormInit("#Model.PropertyImageIds")
var EditFormInit = function (imageIds) {
var imageIdsArr = imageIds.split(",");
var imageFiles = [];
imageIdsArr.forEach(function (ImageId) {
var requestData = { imageId: parseInt(ImageId) };
//var reqUrl = "?imageId=";
//reqUrl = reqUrl.concat(requestData.imageId.toString());
$.ajax({
type: "POST",
url: "/Admin/PropertyImage/GetImageInfo",
data: requestData,
contentType: "text/json; charset=utf-8",
dataType: "json",
success: function (data, status, jqXHR) {
var image = { fileName: data.fileName, size: data.size, thumbnail: data.thumbnailURI }
imageFiles.push(image);
}
});
});
Try:
contentType: "application/json"
This should work
so i finally realised why the controller was not getting hit, and resolved that issue. The $.ajax was passing the controller a JSON request, which was obviously failing.Once I removed the offending lines, the controller breakpoint finally got hit.
$.ajax({
type: "POST",
url: "/Admin/PropertyImage/GetImageInfo",
data: requestData,
success: function (data, status, jqXHR) {
var image = { fileName: data.fileName, size: data.size, thumbnail: data.thumbnailURI }
imageFiles.push(image);
}}
);
Even though the response from the controller is now coming back, the imageFiles array is still null. What am I doing wrong here?

passing an array of int to MVC controller using ajax javascript

What am I doing wrong here?
I can successfully pass 4 bool params to a controller. Now I want to pass an array of int to my controller but it doesn't work - I've left my working code in the example(commented out) so you can see I'm not changing that much - I think I'm missing something simple (it is 17:44 afterall!!!). I can see the array is populated using the alert(rolesChecked); statement:
var rolesChecked = [];
$('[type="checkbox"].role-checkbox').each(function () {
if (this.checked)
{
rolesChecked.push($(this).val());
}
});
alert(rolesChecked);
//var administrator = $('#cbAdministrator').is(":checked");
//var manager = $('#cbManager').is(":checked");
//var technician = $('#cbTechnician').is(":checked");
//var transcriber = $('#cbTranscriber').is(":checked");
if (rolesChecked.count > 0){//administrator || manager || technician || transcriber) {
$.ajax({
url: '#Url.Action("GetFutureHolidays", "Employee")',
type: 'GET',
dataType: 'json',
// we set cache: false because GET requests are often cached by browsers
// IE is particularly aggressive in that respect
cache: false,
data: {
roleIdXXXs: rolesChecked
//includeAdministrator: administrator,
//includeManager: manager,
//includeTechnician: technician,
//includeTranscriber: transcriber
},
success: function (data) {
//do something...
}
});
}
Controller Action:
public string GetFutureHolidays(List<int> roleIdXXXs)//bool includeAdministrator, bool includeManager, bool includeTechnician, bool includeTranscriber)
{
//do something
}
with the old code, the controller action would be hit... with the array, it never gets hit... What am I missing here...
also, I think List<int> roleIdXXXs should be fine, but I also tried List<string>, int[] and string[] in case it isn't!!!
You need to add the traditional: true ajax option to post back an array to the collection
$.ajax({
url: '#Url.Action("GetFutureHolidays", "Employee")',
type: 'GET',
dataType: 'json',
cache: false,
data: { roleIdXXXs: rolesChecked },
traditional: true, // add this
success: function (data) {
}
});
Refer also the answer to this question for more detail on what the options does and the form data it generates.
In your if statement, instead of rolesChecked.count, use rolesChecked.length
You can't submit a list like this from Ajax, the quickest fix in the process you are using is to use serialization-desalinization process, you can send it as
roleIdXXXs: JSON.stringify(rolesChecked)
on Action:
public ActionResult GetFutureHolidays(string rolesChecked)
{
var test = new JavaScriptSerializer().Deserialize<List<int>>(rolesChecked);
}
You should use JSON.stringify() on you AJAX call lice this:
data: {
roleIdXXXs: JSON.stringify(rolesChecked)
//includeAdministrator: administrator,
//includeManager: manager,
//includeTechnician: technician,
//includeTranscriber: transcriber
}

string[] via Ajax and ASP.Net (MVC)

my problem is following.
I try to parse some data via ajax, passing the data to my controller:
AJAX
$.ajax({
type: "GET",
url: "ParseOrganizaitonPath",
data: {
organizationPath: $('#organizationPath').val()
},
success:
function (data) {
//data is from type string with value "System.string[]"
//but should be from type System.string[]
});
}
});
Controller
public string[] ParseOrganizaitonPath(string organizationPath)
{
List<string> organizations = organizationPath.Split('/').ToList();
return organizations.ToArray();
}
I am reaching the controller method and in it everything is fine, but the data that is comming back (ajax part, success method) is just a string ("System.string[]", data[0] S, data[1]y data[2]s...) but not the data I want. (For example if i pass the input "test/one" I want to have as result data[0] test, data[1] one)
Hope you understand what my Problem is.
Thanks in advance!
Julian
Have to tried to use the JavaScriptSerializer? Have a look at this example:
public string ParseOrganizaitonPath(string organizationPath)
{
List<string> organizations = organizationPath.Split('/').ToList();
System.Web.Script.Serialization.JavaScriptSerializer oSerializer =
new System.Web.Script.Serialization.JavaScriptSerializer();
return oSerializer.Serialize(organizations);
}
To deserialize the JSON string with JavaScript you can use the parse function:
var array = JSON.parse(data);
I found a way where you don't have to serialize it (on c# site) and parse it (on javascript site)
Just use the JSON Method that is inherited from the Controller and return an JsonResult:
public JsonResult ParseOrganizaitonPath(string organizationPath)
{
List<string> organizations = organizationPath.Split('/').ToList();
return JSON(organizations);
}
On the client site (javascript) you have to use JSON.stringfy(dataObject) for data that you want to send to your controller-method.
$.ajax({
type: "POST",
dataType: "json",
contentType: "application/json; charset=utf-8",
url: "ParseOrganizaitonPath",
data: JSON.stringify(myDataObject),
success:
function (data) {
//use your data
});
}
});
That's how it worked for me.
Good luck!
Julian

Categories