My json format is different than default json format accepted by jqgrid , but still code working . How? - json

Situation : I am modifying a friend's web application project . It uses spring MVC and java ,JQgrid and GSON .
Project has a Student.java model class ,StudentDaoImpl.java DAO class and a buisness class containing listStudentData() service that returns a list of Student objects , and project is using jqGrid jquery plugin to display student data in view.jsp.
View.jsp once loaded makes the following ajax request to retrieve student data :
function initiate() {
$.ajax({
type : 'GET',
dataType : "json",
url : 'listStudentData',
success : function (data)
{
$("#tabel").jqGrid({
data: data,
colNames: ["name" ,"id"],
datatype: "local",
colModel:[{
name : 'studentName',
index : 'studentName',
width : '290px'
}, {
name : 'studentId',
index : 'studentId',
width : '220px'
}]
rowNum:25,
viewrecords: true,
pager: "#div",
scrollOffset: 0,
emptyrecords:"No records",
height: 'auto',
caption: "student data",
grouping: false,
groupingView : {},
});
}
});
}
Controller handling this response :
#RequestMapping(value = "/listStudentData", method = RequestMethod.GET)
public #ResponseBody
String listStudentData() {
final List<Student> list = studentBusiness.listStudentData();
return gson.toJson(list);
}
My json response from this controller is as follows :
[{"studentName":"x" , "StudentId" : "x#gmail.com" },{"studentName":"Y" , "StudentId" : "Y#gmail.com"}]
And code is working fine and giving correct output!
Problem : Now i was going through documentation of jqgrid (http://www.trirand.com/jqgridwiki/doku.php?id=wiki:retrieving_data)
there it is clearly stated that json format expected by jqgrid is as follows :
{
"total": "xxx",
"page": "yyy",
"records": "zzz",
"rows" : [
{"id" :"1", "cell" :["cell11", "cell12", "cell13"]},
{"id" :"2", "cell":["cell21", "cell22", "cell23"]}
]
}
and json format generated by gson library that is sent as response is different than this format then how it is working correctly ? I searched the project for a custom JsonReader but couldn'tfind any . Am i missing something if not then how is this code working ?

See the gson reference for gson.toJson(obj)
public String toJson(Object src)
This method serializes the specified object into its equivalent Json representation. This method should be used when the specified object is not a generic type. This method uses Object.getClass() to get the type for the specified object, but the getClass() loses the generic type information because of the Type Erasure feature of Java. See the official document Gson
Parameters: src - the object for which Json representation is to be
created setting for Gson Returns: Json representation of src.
Check this Demo which uses the same data as your json to create jQgrid.

Your json-response is a json array. Therefore, I guess that the section 'Array Data' of the manual applies. You tell it to accept an array by using datatype: "local" (which is, as stated by the manual, the same as datatype: "clientSide")
With colName you already provide the correct information how to interpret the array.
You could try this by changing the value of datatype and see, whether the array response is still used correctly.

Related

Monaco editor default json uri schema

I'm using monaco editor to edit JSON and I would like to set a custom diagnostic option.
I'm trying that https://microsoft.github.io/monaco-editor/playground.html#extending-language-services-configure-json-defaults
// Configures two JSON schemas, with references.
var jsonCode = [
'{',
' "p1": "v3",',
' "p2": false',
"}"
].join('\n');
var modelUri = monaco.Uri.parse("a://b/foo.json"); // a made up unique URI for our model
var model = monaco.editor.createModel(jsonCode, "json", modelUri);
// configure the JSON language support with schemas and schema associations
monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
validate: true,
schemas: [{
uri: "http://myserver/foo-schema.json", // id of the first schema
fileMatch: [modelUri.toString()], // associate with our model
schema: {
type: "object",
properties: {
p1: {
enum: ["v1", "v2"]
},
p2: {
$ref: "http://myserver/bar-schema.json" // reference the second schema
}
}
}
}, {
uri: "http://myserver/bar-schema.json", // id of the second schema
schema: {
type: "object",
properties: {
q1: {
enum: ["x1", "x2"]
}
}
}
}]
});
monaco.editor.create(document.getElementById("container"), {
model: model
});
Where does uri: "http://myserver/foo-schema.json" come from ? I just want to use default JSON schema. Not my own.
Setting uri like this works :
uri: "http://localhost:4200/assets/monaco-editor/min/vs/language/json/jsonMode.js",
But is there a clean way to set this value ? Maybe uri value for JSON is available somewhere ? I searched through monaco.languages.json.jsonDefaults but I did not find anything.
"http://myserver/foo-schema.json" is an arbitrary value-- you can make it anything you want. It only matters if you are also using enableSchemaRequest-- in which case it should point to the location that you want the schema to be fetched from-- but you're not doing that, so that doesn't matter. In fact, everything related to this URI is irrelevant to what you are trying to do, if I'm understanding your intent correctly.
When you say "I just want to use default JSON Schema, Not my own", I think what you mean to say is that you just want to ensure that it is valid JSON, right? Because, there is no such thing as "default JSON Schema"-- by definition, it is defined by you-- but there is such a thing as a formal definition of what JSON is (JSON Schema, on the other hand, assumes that you are already starting with valid JSON, and allows you to then define a schema that your (valid) JSON must conform to).
Assuming you just want to ensure it is valid JSON (but you don't care that the json conform to some custom schema), setting the language to 'json' is all you need to do and your code can be as simple as:
var myBadJSONText = '{this is not : "JSON"}'
monaco.editor.create(document.getElementById('container'), {
language: 'json',
value: myBadJSONText
});
which running in the Monaco playground gives you:

TypeScript / Angular 2 creating a dynamic object deserializer

So I am coming from a background of C# where I can do things in a dynamic and reflective way and I am trying to apply that to a TypeScript class I am working on writing.
Some background, I am converting an application to a web app and the backend developer doesn't want to change the backend at all to accommodate Json very well. So he is going to be sending me back Json that looks like so:
{
Columns: [
{
"ColumnName": "ClientPK",
"Label": "Client",
"DataType": "int",
"Length": 0,
"AllowNull": true,
"Format": "",
"IsReadOnly": true,
"IsDateOnly": null
}
],
Rows:[
0
]
}
I am looking to write an Angular class that extends Response that will have a special method called JsonMinimal which will understand this data and return an object for me.
import { Response } from "#angular/http";
export class ServerSource
{
SourceName: string;
MoreItems: boolean;
Error: string;
ExtendedProperties: ExtendedProperty[];
Columns: Column[];
}
export class ServerSourceResponse extends Response
{
JsonMinimal() : any
{
return null; //Something that will be a blank any type that when returned I can perform `object as FinalObject` syntax
}
}
I know StackOverflow isn't for asking for complete solutions to problems so I am only asking what is one example taking this example data and creating a dynamic response that TypeScript isn't going to yell at me for. I don't know what to do here, this developer has thousands of server-side methods and all of them return strings, in the form of a JSON or XML output. I am basically looking for a way to take his column data and combine it with the proper row data and then have a bigger object that holds a bunch of these combined object.
A usage case here after that data has been mapped to a basic object would be something like this.
Example:
var data = result.JsonMinimal() as LoginResponse; <-- Which will map to this object correctly if all the data is there in a base object.
var pk = data.ClientPK.Value;
I'm not exactly sure I understand, but you may want to try a simple approach first. Angular's http get method returns an observable that can automatically map the response to an object or an array of objects. It is also powerful enough to perform some custom mapping/transformation. You may want to look at that first.
Here is an example:
getProducts(): Observable<IProduct[]> {
return this._http.get(this._productUrl)
.map((response: Response) => <IProduct[]> response.json())
.do(data => console.log('All: ' + JSON.stringify(data)))
.catch(this.handleError);
}
Here I'm mapping a json response to an array of Product objects I've defined with an IProduct interface. Since this is just a "lambda" type function, I could add any amount of code here to transform data.

How can I use AJAX with web methods to send JSON objects to a jQuery DataTable using asp.net?

So I have the jQuery datatable using AJAX to call for the JSON in this format.
$(document).ready(function () {
$('#test').DataTable({
ajax:{
url:"players.json",
dataSrc:""
},
columns: [
{data: "id"},
{ data: "player" },
{ data: "points" },
{ data: "steals" },
{ data: "blocks" },
{ data: "assists" },
{ data: "MPG" },
{ data: "shot %" },
{ data: "3 %" }
]
});
});
My aspx.cs file has a method to create the JSON file which works.
[System.Web.Services.WebMethod]
public static void loadTable()
{
NBAPlayerRepository players = new NBAPlayerRepository();
DataTable dt = players.GetAll();
var json = dt.ToJson();
System.IO.File.WriteAllText(#"C:\Users\wheres\Downloads\nbaStats\nbaStats\nbaStats\players.json", json);
}
And the JSON looks like this:
[{"id" : "67926aa7-46b7-4418-96db-fc7e5216aac4","playername" : "Wilson Heres","points" : "34534","steals" : "34","blocks" : "34","assists" : "343","mpg" : "343","shootingpercentage" : "33.3429985046387","threepointpercentage" : "33.3429985046387"}
,{"id" : "6dc42e0b-8750-463d-a9ef-5a025a27154b","playername" : "Wilson Heres","points" : "34534","steals" : "34","blocks" : "34","assists" : "343","mpg" : "343","shootingpercentage" : "33.3429985046387","threepointpercentage" : "343.334014892578"}
,{"id" : "f727130c-5b94-4730-a653-cfb603c73b8a","playername" : "Wilson Heres","points" : "34534","steals" : "34","blocks" : "34","assists" : "343","mpg" : "343","shootingpercentage" : "33.3429985046387","threepointpercentage" : "343.334014892578"}
]
But now I am getting this error "jquery.dataTables.min.js:48 Uncaught TypeError: Cannot read property 'length' of undefined"
Edit: This all works now. Just had to add dataSrc:""
Cleaned-up version of your DataTables initialization
$(document).ready(function () {
$('#test').DataTable({
ajax: {
url: "players.aspx/loadTable"
},
columns: [
{ data: "id" },
{ data: "player" },
{ data: "points" },
{ data: "steals" },
{ data: "blocks" },
{ data: "assists" },
{ data: "MPG" },
{ data: "Shot %" },
{ data: "3 %" },
]
});
});
This may seem like a lot of stuff was removed from your code, so let me make some explanations/assumptions about what was changed.
Assumptions
First, an assumption: DataTables will always try to use a GET request, not a POST when first getting the data from the table, so make sure that your data processing code expects that.
I also am assuming that you have no strong desire to have your Ajax separate from your initialization and that was just how you decided to do it as a first attempt. If that is the case, let me know and I'll update the code to match that.
Explanation
Your formatting is incorrect in some areas and against DataTables standard in others, so this version should do most of what you were trying to do in a much simpler form. A lot of your Ajax options are unnecessary because they are already the default (JSON for the data type, for example), which is why they have been removed.
One nice thing about DataTables is that you can have the Ajax options in the initialization, which is what I have done here. You do lose the success and failure callbacks but I think that for debugging purposes they aren't really necessary and having any extra code increases the amount of stuff to debug (I don't even use those callbacks in most of my final code).
Most of the other changes were mainly incorrect nomenclature (e.g. data instead of title in the column definitions.
Disclaimer
While I would recommend these changes in general just to improve your code, I would make sure to take a look at the format of the JSON that is being sent to and from the server. If you don't know how to do that I'd recommend downloading Fiddler to 'listen in' on the JSON data being sent.
If your JSON is wrong, no amount of changes to the page are going to make the table appear.
Finally, make sure you have no JS errors on the page. Use your browser's developer console (F12) to check that.
If you do find any JS errors, post them in your question. I'd also recommend posting the JSON data being sent to the question as well so that we can ensure the format is correct.

How to parse dynamic json data in WebAPI controller from jqgrid edit url

In after inline edit free jqgrid sends variable number of columns to ASP.NET MVC4 WebAPI controller using POST method.
Posted data contains json string below.
json string posted to controller in POST body looks like:
{"Toode":"","Kogus":"0.0000",
"Nimetus":"1","Mootyhik0_nimetus":"",
"Reanr":"2",
"_oper":"edit","_rowid":"1673",
"_dokdata":"[
{\"name\":\"Maksetin1_tingimus\",\"value\":\"\"},
{\"name\":\"Kinnitatud\",\"value\":\"False\"}]"
}
It has 3 regions of properties:
Order details. Dynamic properties "Toode":"","Kogus":"0.0000","Nimetus":"1","Mootyhik0_nimetus":"",
"Reanr":"2"
This list may change on runtime depending on user preferences.
This is created by using jqgrid extraparam: getDetails() setting.
Fixed properties stating with underscore `"_oper":"edit","_rowid":"
Those are
_oper and _rowid are always present
jqgrid adds them automatically.
Order data. fixed property _dokdata which contains json array of dynamic properites {\"name\":\"Maksetin1_tingimus\",\"value\":\"\"},{\"name\":\"Kinnitatud\",\"value\":\"False\"}
This is created from jqgrid colmodel.
This list may change in runtime and may contain same poperty names as in p.1 order details.
How to get this data in controller ? Probably it shoud be parsed into two dictionaries . Is it possible to force WebAPI to pass this data as classes/collection to controller or should it parsed manually?
jqgrid settings are from answer Using jqGrid's inline-editing with RESTful urls?
Those and serialize methods can changed if this makes data passing more reasonable.
Resulting WebAPI should have easily understandable data format (good API) since it will be used by third party applications also.
$.extend($.jgrid.defaults, {
ajaxRowOptions: { contentType: "application/json", async: true },
serializeRowData: function (data) {
var propertyName, propertyValue, dataToSend = {};
for (propertyName in data) {
if (data.hasOwnProperty(propertyName)) {
propertyValue = data[propertyName];
if ($.isFunction(propertyValue)) {
dataToSend[propertyName] = propertyValue();
} else {
dataToSend[propertyName] = propertyValue;
}
}
}
return JSON.stringify(dataToSend);
}
});
Update
serializeRowData is changed to
serializeRowData: function (data) {
return JSON.stringify({
headerData: $("#_form").serializeArray(),
rowData: data
} );
}
This produces bloated json for headerData:
{"headerData": [
{"name":"Tasudok","value":"134"},
{"name":"Kuupaev","value":"2015-11-23"},
{"name":"Dokumnr","value":"135319"}
],
"rowData": {"Toode":"",
"Kogus":"0.0000",
"Nimetus":"öäölä<a",
"_rowsum":"0.00",
"Id":"1639",
"Dokumnr":"135319",
"_oper":"edit",
"_rowid":"1639"
}
}
How remove name and value properties from headerData so that it contains property name and value pairs like in rowData:
headerData: {
"Tasudok": "134",
"Kuupaev": "2015-11-23",
"Dokumnr": "135319"
}

Sending complex JSON with fetch, save, and delete on a model or collection

We have an internal API that was specifically built to be used with a new piece of software I'm building that runs on Backbone. The API has a single URL and takes JSON as input to determine what it needs to return. It essentially allows me to build custom queries with JSON that return exactly what I'm looking for.
Thing is this JSON can get pretty verbose and is often 3–4 levels deep, but sometimes may just be a few lines and just 1 level deep.
First question first: How do I send a string of JSON along with the ID when I do a fetch()? Do I have to set these parameters as the model or collection's defaults?
Here is an example of a really simple string to get a specific user's info
{
"which" : "object",
"object" : {
"type" : "customer",
"place" : "store",
"customerID" : "14"
}
}
As others have suggested it will likely be challenging to work with SOAP, but it shouldn't be impossible. Backbone models and collections communicate with the server through the sync operation; you should be able to customize that. I think something along these lines might get the ball rolling (for models):
Backbone.SoapyModel = Backbone.Model.extend({
sync: function(method, model, options) {
// force POST for all SOAP calls
method = 'create';
options = _.extend(options, {
// Setting the data property will send the model's state
// to the server. Add whatever complexity is needed here:
data: JSON.stringify({
"which" : "object",
"object" : model.toJSON()
}),
// Set the request's content type
contentType: 'application/json'
});
// Defer the rest to Backbone
return Backbone.sync.apply(this, [method, model, options]);
}
});
var SoapyModelImpl = Backbone.SoapyModel.extend({
url: '/test'
});
var soapTest = new SoapyModelImpl({
id: 42,
name: 'bob',
address: '12345 W Street Dr',
phone: '867 5304'
});
soapTest.fetch();