Extjs store reader fully qualified json property names - json

Using Extjs 3+ and server side is sending back the following JSON:
{"com.klistret.cmdb.ci.pojo.QueryResponse": {"com.klistret.cmdb.ci.pojo.successful":true,"com.klistret.cmdb.ci.pojo.count":1,"com.klistret.cmdb.ci.pojo.elements":{"com.klistret.cmdb.ci.pojo.id":123,"com.klistret.cmdb.ci.pojo.name":"Mars","com.klistret.cmdb.ci.pojo.fromTimeStamp":"2010-07-08T16:38:00.478+02:00","com.klistret.cmdb.ci.pojo.createTimeStamp":"2010-07-08T16:38:00.478+02:00","com.klistret.cmdb.ci.pojo.updateTimeStamp":"2010-10-25T15:02:09.446+02:00","com.klistret.cmdb.ci.pojo.type":{"com.klistret.cmdb.ci.pojo.id":1,"com.klistret.cmdb.ci.pojo.name":"{http:\/\/www.klistret.com\/cmdb\/ci\/element\/logical\/collection}Environment","com.klistret.cmdb.ci.pojo.fromTimeStamp":"2009-08-05T11:20:12.471+02:00","com.klistret.cmdb.ci.pojo.createTimeStamp":"2009-08-05T11:20:12.471+02:00","com.klistret.cmdb.ci.pojo.updateTimeStamp":"2009-08-05T11:20:12.471+02:00"},"com.klistret.cmdb.ci.pojo.configuration":{"#www.w3.org.2001.XMLSchema-instance.type":"com.klistret.cmdb.ci.element.logical.collection:Environment","#Watermark":"past","com.klistret.cmdb.ci.commons.Name":"Mars"}}}}
The reader is setup up as follows:
var reader = new CMDB.JsonReader(
{
totalProperty : 'com.klistret.cmdb.ci.pojo.count',
successProperty : 'com.klistret.cmdb.ci.pojo.successful',
idProperty : 'com.klistret.cmdb.ci.pojo.id',
root : 'com.klistret.cmdb.ci.pojo.elements'
},
[
{name: 'Id', mapping: 'com.klistret.cmdb.ci.pojo.id'},
{name: 'Name', mapping: 'com.klistret.cmdb.ci.pojo.name'}
]
);
The store as:
var ds = new Ext.data.Store({
proxy : new Ext.data.ScriptTagProxy({
url : 'http://sadbmatrix2:55167/CMDB/resteasy/element'
}),
reader : reader
});
The reader extends the Ext.data.JsonReader as explained by http://erichauser.net/2007/11/07/more-wcf-json-and-extjs/ to remove the "com.klistret.cmdb.ci.pojo.QueryResponse" start node in the JSON returned from the server.
The extended reader never gets called. Assuming the problem is due to has fully qualified property names in the JSON object returned (ie. "com.klistret.cmdb.ci.pojo.name" rather than just "name").
Anybody use gotten around this?

We worked it out (well, mostly Matthew did) in the comments:
ScriptTagProxy needs the server to wrap the JSON data in a function call so that your local code can get access to it.
Instead of the server emitting something like:
{here:'is data}
it needs to return
somefunc("{here:'is data'}");
That way, your client-side implementaiton of somefunc() is called and can process the returned data.

Related

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();

Get JSON data from WebAPI & Load data into Store

I am learning ExtJS-4.2, I was following their MVC tutorial...
I built my controller, view, model, store... My Store had hard-coded data. I have a working WebAPI for testing, which sends result in json format...
What the tutorial is talking about how to read from local file and send to an API,
what i want to read from API and load my data into the store...
Ext.define('AM.store.Productstore',
{
extend : 'Ext.data.Store',
model : 'AM.model.Productmodel',
autoload : true,
proxy : {
type : 'AJAX',
url : 'localhost/mfw/api/products/all'
//tutorial is no help any furthur from this point on
}
});
My URL is localhost/mfw/api/products/all
and my returning json is
[{"ID":1,"Name":"aa","Category":"A","Price":200.00},
{"ID":2,"Name":"bb","Category":"B","Price":200.00
{"ID":3,"Name":"cc","Category":"C","Price":200.00},
{"ID":4,"Name":"dd","Category":"D","Price":200.00},
{"ID":5,"Name":"ee","Category":"E","Price":200.00},
{"ID":6,"Name":"ee","Category":"F","Price":200.00}]
any help?
Please change your proxy type to 'rest' instead of 'Ajax'. More over mention your reader config. Did you map your json key with fields in model.
please refer sencha guide for more clarity.
http://docs.sencha.com/ext-js/4-2/#!/guide/data
Thanks
Here is a jsfiddle showing a grid with your data. One of the key things is the root property of the json reader. Since your data does not have a root you can leave the root property out and it should work. If you data is wrapped inside another field ie root field then specify root: 'myrootfield' in the reader. So here is your proxy. Also in your model specify the key field using idProperty in your case it is 'ID', I think extjs defaults to idProperty of 'id' lowercase so better to just specify it directly.
proxy : {
type : 'rest',
url : 'localhost/mfw/api/products/all'
reader: {
type: 'json'
}
}

ExtJS 4 - Json Writer does not have Record config like Json Reader does

Ok guys, working ExtJS4 and I have pretty much the exact opposite problem this guy did:
How do I get an ExtJS JsonStore to put the JSON data directly into the request body?
In my application I have a nested data structure being loaded with associated models.
CakePHP in the backend expects (in pseudocode) the following format in saves:
[
{
[Model]
[Field1]: [Value1],
[Field2]: [Value2],
[Field3]: [Value3]
},
{
[Model]
[Field1]: [Value1],
[Field2]: [Value2],
[Field3]: [Value3]
}
]
This is what ExtJS is currently sending to the server:
[
{
[Field1]: [Value1],
[Field2]: [Value2],
[Field3]: [Value3],
[Model] : null
}
]
So, for some reason it's including the model as a null value and putting the parameters in the root node of the Json object.
The server sends the data to the client in a similar fashion but the Json Reader for the Json Proxy has a record parameter (See here). Unfortunately the Json Writer has no such property (not even undocumented as I have tried setting it).
Currently my workaround on the back end is:
$json = Set::insert($json, 'Model', $json);
But it would be good if there was a better way to accomplish this.
Update:
To further expand, I am loading one store which loads nested Json data that automatically populates associated models in the client. (This is all done with Extjs methods without any custom code).
I have tried the root property in the Json writer but unforunatly with batch records it formats the request like this:
{
[Root] : [
{
[Field1]: [Value1],
[Field2]: [Value2],
[Field3]: [Value3],
[Model] : null
},
{
[Field1]: [Value1],
[Field2]: [Value2],
[Field3]: [Value3],
[Model] : null
}
]
}
I have also tried Bancha (http://banchaproject.org) but I was unable to get that to work with Sencha Architect (which is being used for this project) and the solution they have provided at the moment was a "workaround" (which I was unable to get working).
Thank you,
-T6
The thing with the modelName:null looks like you have some custom code already here. To just get the data in a named object, the Writer has a property 'root' in ExtJS and 'rootProperty' in Sencha Touch, this could help.
There's also a framework which does all of this marshaling for you, see banchaproject.org
It costs a bit, similar to ExtJS, but it will do a lot of this work for you.
In cases where I've needed to customize the format in which the Writer sends the request, I"ve simply created my own custom writer (extending Ext.data.writer.Json), and have overwritten the writeRecords() method with whatever logic I needed to format the request correctly.

working with JSON data, trying to parse nested data

I just working with JSON data and am playing around with jQuery and Ajax requests. Pretty basic stuff, but here's my problem.
I have a basic data set which I was using for time tracking. I know how to parse the simple JSON data like this:
{
"end" : "1/18/2011",
"start" : "1/18/2011",
"task" : "Code Review",
},
It's the more complicated stuff I'm trying to parse like this where I'm trying to pull the "time" data out.
{
"end" : "1/17/2011",
"start" : "1/17/2011",
"task" : "Exclusive Brands",
"time" : {
"analysis" : 4,
"documentation" : 3,
"meetings" : 2
}
This is the code for the script I've been using to parse the simple data:
$(function() {
$('.load').click(function(){
$.getJSON("data.js",function(data){
$.each(data.timesheet, function(i,data){
var div_data ="<div class='box'>"+data.start+" "+data.task+"</div>";
$(div_data).appendTo("#time-tracking");
});
}
);
return false;
});
});
My question is what's the format to parse the time data, or what's the best way to parse the information nested inside the time element?
Any help will be greatly appreciated.
A JSON string will be parsed into an object. When parsed, the time is the key of one object. You could retrieve the value of this object through the dot operator (.).
data = JSON.parse('{"end":"1/17/2011", "start":"1/17/2011", "task":"Exclusive Brands", "time": {"analysis":4, "documentation":3, "meetings":2 } }')
// => obj
data.time.analysis
// => 4
In your case similarly you could use the data.time.meetings to access your data from remote server.
Unless I am terribly mistaken, since jquery already converted data into a javascript for you, you should be able to access time as if it was a javascript object like so:
var analysis = data.time.analysis;
var documentation = data.time.documentation;
var meetings = data.time.meetings;
etc...

what's basic difference between JsonStore and JsonReader in context to Ext.data?

What's basic difference between JsonStore and JsonReader in context to Ext.data?
I mean when I should go for JsonStore and when I should use JsonReader as for me both are providing same solution.
Actually they are two separate things. A Ext.data.JsonReader reads a given JSON object and returns data records (Ext.data.Record objects) that are later stored by the respective data store.
The Ext.data.Store is the base class for all Ext storages and uses helper objects for retrieving data (Ext.data.DataProxy), for writing data (Ext.data.DataWriter) and for reading data (Ext.data.DataReader). These base classes come in different flavors such as:
Ext.data.DataProxy:
Ext.data.DirectProxy
Ext.data.HttpProxy
Ext.data.MemoryProxy
Ext.data.ScriptTagProxy
Ext.data.DataWriter
Ext.data.JsonWriter
Ext.data.XmlWriter
Ext.data.DataReader
Ext.data.JsonReader
Ext.data.XmlReader
This all builds up to a very extendable component that allows the developer to configure exactly what he needs to tweak. To make it easier for developers (especially new ones) Ext comes with some pre-configured data stores:
Ext.data.ArrayStore to make reading from simple Javascript arrays easier
Ext.data.DirectStore, just a store preconfigured with an Ext.data.DirectProxy and an Ext.data.JsonReader
Ext.data.JsonStore, just a store preconfigured with an Ext.data.JsonReader
Ext.data.XmlStore, just a store preconfigured with an Ext.data.XmlReader
So actually a Ext.data.JsonStore is just a convenience class to make it easier for the developer.
The following two snippets will create the same (or comparable) stores:
var store = new Ext.data.JsonStore({
url: 'get-images.php',
root: 'images',
idProperty: 'name',
fields: ['name', 'url', {name:'size', type: 'float'}, {name:'lastmod', type:'date'}]
});
// or
var store = new Ext.data.Store({
url: 'get-images.php',
reader: new Ext.data.JsonReader({
root: 'images',
idProperty: 'name',
fields: ['name', 'url', {name:'size', type: 'float'}, {name:'lastmod', type:'date'}]
});
});
A JsonReader reads JSON from a data source into an Ext Store. JsonData is not a specifically-defined Ext object, although maybe you've seen it as a variable name? In what context are you using it?