How to use array string in jQuery ajax call? - javascript

By using jQuery, I am trying to save my string array in backend and following is my approach.
1.Using jQuery ajax sending array.
var tagTexts = $(ul li.select2-selection__choice")
.toArray()
.map(function(i){
return i.innerText;
});
tagTexts = tagTexts.join(',');
$.ajax({
type: 'POST' ,
url: '/tag/tagList',
dataType: 'json',
data: {
tagTexts: tagTexts
},
error: function(err) {
console.log(err);
},
success: function(response) {
//Process Response
}
});
2.In backend it is retrieved as follows:
#ResponseBody
#RequestMapping(value = "/tag/tagList", method = RequestMethod.POST)
public String saveTagList(HttpServletRequest request,
#RequestParam(value = "tagTexts", required = false)List<String>tagTexts) {
System.out.println(tagTexts);
String response = tagService.saveTags(tagTexts);
return response;
}
a) Using array join method
Following is the string array captured:
["Drone", "Richard Feynman, PHD", "Yatch"]
After using array join method this gets changed as follows:
Drone,Richard Feynman, PHD,Yatch
In java execution (backend) this gets displayed as follows:
[Drone, Richard Feynman, PHD, Yatch]
b) Using JSON.stringify method
After using JSON.stringify method, the captured array gets displayed as follows:
["Drone", "Richard feynman, PHD", "Yatch"]
This looks fine at js level but this entire line is considered as a string and it is displayed at the backend as follows:
[["Drone", "Richard feynman, PHD", "Yatch"]].
I am expecting my code to work as follows:
Comma character in raw data element captured should not split.
The entire array should not appear as a string in the backend.
Is there any better way to achieve this??

You can create a custom request object like this:
public class TagListRequest {
private List<String> tagTexts;
// getter and setter
}
You now can use this with #RequestBody in your request mapping:
#ResponseBody
#RequestMapping(value = "/tag/tagList", method = RequestMethod.POST)
public String saveTagList(#RequestBody TagListRequest request) {
System.out.println(request.getTagTexts());
String response = tagService.saveTags(request.getTagTexts());
return response;
}
Spring internally maps the JSON body of your request to the TagListRequest object using Jackson.
With this solution you do not need to parse the data manually using a separator.

Your javascript with JSON.stringify is correct solution. You just need to parse the JSON in java backend. For example,
import org.json.simple.JSONObject;
JSONParser parser = new JSONParser();
JSONObject json = (JSONObject) parser.parse(tagTexts);
See How to convert jsonString to JSONObject in Java for alternative ways how to parse JSON in java.

Related

How to access a java Map<String, String> from javascript using Spring MVC

What is the best way to access a java Map from javascript while using Spring MVC?
I'm building a webpage where depending on the values you chose from a checkbox, a dynamic text will appear in another div with further details regarding that option by using getElementById("element").innerHTML=${var}.
I'm using Maps to populate the checkbox options, and it does works fine in JSPs but simply won't work in javascript scriptlets or external .js files. It just understands it as a string, not as a Map or Array.
The following code is what I've got so far:
Properties file:
checkBoxItems={'0':'The Value'}
myMapObject={'0','Map Stuff'}
In Controller java file:
#Controller
#RequestMapping(value = "/example")
public Class ExampleController
{
#Value("#{${checkBoxItems}}")
Map<String, String> checkBoxOptions;
#Value("#{${myMapObject}}")
Map<String, String> myMapObject;
#RequestMapping(value = "/newExample", method = RequestMethod.GET)
public String Hello(Model model)
{
model.addAttribute("checkBoxOptions", checkBoxOptions);
model.addAttribute("myMapObject", myMapObject);
return "view";
}
}
in JSP: (I've simplified to show what I aim to achieve)
<form:select class="custom-select" id="metodologia" path="metodologia"
onchange="FillWithComplement('${myMapObject}')">
<form:option value="-">Select an Option</form:option>
<form:options items="${checkboxOptions}"/>
</form:select>
In the first javascript trial:
<script>
function FillWithComplement(MapObject)
{
document.getElementById("div").innerHTML = MapObject;
}
</script>
the output is:
{0=Map Stuff}
And it also doesn't work if I do:
<script>
function FillWithComplement(MapObject)
{
var newMap = new Map(MapObject);
document.getElementById("div").innerHTML = newMap;
}
</script>
And I am aware I might not have enough javascript knowledge do handle this correcty.
Thanks.
EDIT:
As proposed by Yan Khonski, passing data as JSON by asynchronous request (ajax) worked with minor changes.
dataType: 'json' returns a JSON object, so it is needless to implement a JSON parsing method.
The final code:
var globalMetodologiaComplemento;
$(document).ready(function () {
$.ajax({
type: 'GET',
url: '/gla/getMet',
dataType: 'json',
success: function (data) {
globalMetodologiaComplemento = data;
console.log(globalMetodologiaComplemento[0]);
}
});
});
(...)
You can have a REST end-point which returns data in JSON format. Then your client - javascript code, will make an asynchronous request (after the page has loaded) to the rest end-point and get the data. Then js code will parse JSON into object and can work with it.
1) Controller returns model and view. The view is a JSP page.
#Controller
#RequestMapping(value = "/example")
public Class ExampleController
{
#Value("#{${checkBoxItems}}")
Map<String, String> checkBoxOptions;
#Value("#{${myMapObject}}")
Map<String, String> myMapObject;
#RequestMapping(value = "/newExample", method = RequestMethod.GET)
public String Hello(Model model) {
model.addAttribute("checkBoxOptions", checkBoxOptions);
model.addAttribute("myMapObject", myMapObject);
return "view";
}
#ResponseBody
#GetMapping("/additional-data")
public String getData() {
return objectMapper.writeValueAsString(yourObject);
}
}
Check Jackson library to serialize objects into JSON.
2) Once jsp page is loaded, you can make an asynchronous (AJAX) request to another end-point in your controller. This endpoint will return JSON data (you will have to serialize your object into JSON).
https://api.jquery.com/jquery.ajax/
How to parse JSON data with jQuery / JavaScript?
https://stackoverflow.com/a/32593283/1839360
$(document).ready(function(){
$.ajax({
type: 'GET',
url: 'http:localhost:8080/example/additional-data',
dataType: 'json',
success: function (data) {
//data downloaded so we call parseJSON function
//and pass downloaded data
var object = $.parseJSON(data); // use browser debugger to see that properties the object has
}
});
});
3) Your client JS code will receive a response from AJAX call and parse the data.

How to pass value from spring controller to javascript function

I am calling controller through javascript function like below and I want to return some value(controller execution time) from controller to same javascript function without using return statement or any other way?
function myFunction(){
var form123 = document.getElementById("myFormSubmit");
form123 .action="userDetailsList";
form123 .method="POST";
form123 .submit();
}
use GSON package this will help output a json String
import com.google.gson.Gson;
#ResponseBody This will not return a view it will return a string to the browser (technically) which jquery will read..
#RequestMapping(value = "/URLHERE", method = RequestMethod.POST)
public #ResponseBody
String CheckAdapter(HttpServletRequest request, HttpSession session) {
Map<String, Object> hm = new HashMap<>();
String a = your Logic here;
hm.put("string", a);
return new Gson().toJson(hm);
}
This is the ajax part
$.ajax({
type: "POST",
url: "URLHERE",
dataType: 'JSON',
success: function (data) {
console.log(data);
}
});
What is ajax?
AJAX, or Asynchronous Javascript And XML, is a client side technique for communication with a web server. ... Instead of making a URL request for another whole page, you use JavaScript to talk to the server and receive smaller pieces of information that can range from HTML to other data formats like JSON/XML/Etc

Sending and receiving an array to a sql database via JSON

I put an array in an object which is send to an java webservice (see javascript.js -> sendDataToWebservice()). The webservice proceeds the array (via gson) and saves it as a String in an sql database (see webservice.java -> handleDataFunction()). When I want to receive the array the data is not properly converted back to an array (see javascript.js -> receiveDataFromWebservice()). Instead of an array the data will be converted to an String like this: "["item1", "item2]".
Do I need to parse the array? I think the problem is that somewhere in between there are added the quotation marks and thus the data is recognized as a string and not an array.
Thanks in advance!
javascript.js
var myArray = new Array();
function sendDataToWebservice() {
// Create the JSON to send to the webservice
var jsonData = {
"action": actionName,
"array": myArray
};
// Send the data
$.ajax({
url: "/xaction/",
type: 'POST',
data: JSON.stringify(jsonData),
contentType: 'application/json; charset=utf-8',
dataType: 'json',
async: true,
success: function (msg) {
// ...
}
});
}
function reveiveDataFromWebservice() {
// Receive the data
jQuery.getJSON("/webservice/getdata", function (returningData) {
if (returningData.success) {
array= returningData.array;
}
});
webservice.java
private void handleDataFunction(inputData) {
// Create a map for the parameters
MapSqlParameterSource namedParameters = new MapSqlParameterSource();
// Create the query string
String query = "my sql query";
// Here I want to retrievethe array as a String to store it in the db
JsonArray jsonArray = currentAntwortFeld.get("array").getAsJsonArray();
// Add the array as an String to the sql parameters
namedParameters.addValue("arraydbfield", jsonArray.toString())
// Execute the sql query
factory.executeUpdate(query, namedParameters);
}
JSON.parse() will turn a string containing an array into an array object.
myArray = JSON.parse(myString)
Can't tell why jQuery isn't already doing that for you though. I thought that was the point of $.getJSON(). But I don't use jQuery, so I don't really know.
For converting from JSON to SQL I implemented as follows:
let jsArray = [1,2,3,4] //Example array in JS
let sqlArray = '{';
jsArray.forEach(element=>sqlArray+=element+',')
sqlArray = sqlArray.substring(0, sqlArray.length-1) + '}'
Now use sqlArray is fit for SQL.

Convert a Java List<String> into a Javascript array

I'm using the jQuery UI autocomplete to show suggestions for a text input field.
The suggestions are stored in a Javascript array called suggestions.
I'm trying to fetch the string values for the suggestions array from a database, but I can't convert the List object to a Javascript array.
The Javascript:
var suggestions = [];
$.get('/mywebapp/autocompleteplayer.html', function(data){
parsed = JSON.parse(data);
suggestions = parsed.split(",");
}, "json");
$('#autocompleted').autocomplete({
data: suggestions,
minLength: 3
});
The Spring MVC controller:
#Controller
public class AutocompletePlayerController {
#RequestMapping(value = "/autocompleteplayer")
public List<String> getPlayerSuggestions(){
List<String> myList;
//code that fills myList with all of the players' full names from the database, omitted for brevity
return myList;
}
}
I know I'm not parsing the AJAX response properly, since I've checked from the browser console that the suggestions array has 0 elements. Can anyone help me? What am I doing wrong here?
You need to use it like this in your js (data is the response entity, not the data - it's in data.data) :
$.get('/mywebapp/autocompleteplayer', function(data){
suggestions = data.data;
$('#autocompleted').autocomplete({ // not sure how to use your plugin
data: suggestions,
minLength: 3
});
}, "json");
And in your spring controller, add the #ResponseBody Annotation
#RequestMapping(value = "/autocompleteplayer")
#ResponseBody
public List<String> getPlayerSuggestions(){
List<String> myList;
//code that fills myList with all of the players' full names from the database, omitted for brevity
return myList;
}
There's no need to JSON.parse anything, jquery already did this.
/mywebapp/autocompleteplayer.html also sounds wrong. The route is autocompleteplayer without .html.
Other than that, suggestions is created async. So your data in autocomplete will always be empty. I didn't use that plugin myself so there might be an update function for the data, otherwise try to put it in the $.get() functions callback.
You can return json array as String in java
#Produces("application/json")
public String getPlayerSuggestions(){
....
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
String jsonString = gson.toJson(myList);
return jsonString;
}
You need to modify your controller like this:
#RequestMapping(value = "/autocompleteplayer", method=RequestMethod.GET)
#ResponseBody
public String getPlayerSuggestions(){
List<String> myList;
JSONArray jsonArray = new JSONArray();
for(String item: myList){
JSONObject jsonObj = new JSONObject();
jsonObj.put("Item", item);
jsonArray.put(jsonObj);
}
return jsonArray.toString();
}
then you can handle your values easy with JSON.
Regards,

send multiple objects via ajax (using angular)

I have a list of user inputs in an object 'data'. (for e.g data.username, data.password, data.age)
i am passing the data object to backend like this using angular.
var submits = "=" + JSON.stringify(data);
$.ajax({
type: "POST",
url: serviceURL,
data: submits
});
I am passing two more objects. selections and grid. how can i pass all these three together in one ajax call ? or do i have to transfer it independently. will it affect the performance if i transfer these details separately.
can i do something like this to send the object together in one ajax call?
var data = {};
data[0] = data1;
data[1] = data2;
How can i retrieve it separately at the server side using c# if at all they are passed together.
Heres the 3 objects that i need to pass
data -->> ["Raul","New York","31"]
selections-->> ["dy.txt","my.txt","yy.txt"]
grid--> ["sesion","id"]
Assuming you have a view model like this in your server side
public class CreateUserViewModel
{
public string UserName{set;get;}
public string Location {set;get;}
public int Age {set;get;}
}
public class RegisterViewModel
{
public CreateUserViewModel User {set;get;}
public List<string> Selections {set;get;}
public List<string> Grid {set;get;}
}
and an MVC action method like this
public ActionResult Create(RegisterViewModel model)
{
// read model and save and return some JSON response
}
You can simply build the javascript object which matches the structure of the view model and post it using angualr's $http service. No need to worrry about setting content-Type or Json stringifying it. Angualr will take care of it.
var model={ User : {} ,Selections :[], Grid=[] };
model.User.Age =23;
model.User.UserName ="test";
model.User.Location="New York";
model.Selections.push("dy.txt");
model.Selections.push("some.txt");
model.Grid.push("session");
model.Grid.push("id");
var url="replcaeUrltoYourActionMethodHere";
$http.post(url, model)
.then(function(response)
{
// do something with the response
// var result= response.data
});
You can send multiple objects / variables in ajax with:
var submits = "=" + JSON.stringify(data);
$.ajax({
type: "POST",
url: serviceURL,
data: {submits : submits, data1:data1, data2:data2}
});
In your C# you can access data1 and 2 in the same way as you handle submits now.
Depending of what is in data1 and data2 you might need to stringify it first.
second option:
You can also if you want to (but it is more ugly) use the stringify on everything at once and only pass the string:
data = {};
data["data1"] = data1;
data["data2"] = data2;
var submits = "=" + JSON.stringify(data);
Are you using WebApi or MVC on the server? If so, the simplest approach would be to create a class which holds the 3 entities you need to send and leverage the built-in model-binding
So in your example you list what looks to be a user form, selections and grids. I'm not really sure what the last two are but an example Model might look something like this:
public class UserSubmissionViewModel
{
public UserSubmissionViewModel() { }
public UserFormModel User {get;set;}
public SelectionsModel Selections { get; set; }
public GridModel Grids { get; set; }
}
Then on your web api controller or your MVC controller you'd have a method such as this:
public async Task<IHttpActionResult> Submit(UserSubmissionViewModel model)
And your javascript would resemble something roughly like this:
var toSend = {"UserFormModel":data, "SelectionsModel":selections, "GridModel":grids};
$.ajax({
type:"POST",
data:toSend, //<--- you might need to JSON.stringify this, cant test this code at the moment
url:serviceURL //<-- Calls your Submit method on the controller
});

Categories