Accessing additional properties from JSON received through store's load method - extjs

I have a grid that loads data via a JSON store, however there are some additional properties beyond the records themselves that I need to access. Here's an example of what the JSON data looks like:
{
success: true,
records: [
{id: 1, name: 'bob'},
{id: 2, name: 'fred'}
],
extraProperty: 'foo'
}
I need to access that extraProperty when the grid data is loaded. So I assume I'd want to a callback, like so:
store.load({
callback: function (records, operation, success) {
//somehow access extraProperty here
}
});
I'm not sure what to do inside that callback. The operation variable, an Ext.data.operation.Operation object, has a private method called getResponse(). It returns an object in Chrome that has a responseJson property, but in IE it instead has a responseText property that needs to be decoded. So I could handle both scenarios, but since it's a private method I don't really want to rely on it in the first place. Any ideas?

Use the keepRawData config on the reader.
store.load({
callback: () => {
const { extraProperty } = store.getProxy().getReader().rawData;
}
});
Depending on your needs, you may also want to look at preserveRawData as well.

did you tried on the store level, something like below
under proxy in the reader config section
proxy: {
type: 'ajax',
actionMethods: {
read: 'GET'
},
headers: {
'Content-Type': 'application/json;charset=utf-8'
},
api: 'your url',
reader: {
extraProperty: 'extraProperty'
}
}

Related

ExtJs (6.0.0) rest service PUT request

I am trying to PUT some data from my frontend (ExtJs) into my backend (Java, Spring). It does not work or I do not get the right clue...
I am on a Ext.grid.Panel where I use the following store which is (nicely) filled and displayed by a this.store.setData( myObject.data.items ) method:
Ext.define( 'NameOfThisClass', {
extend: 'Ext.grid.Panel',
...
store: Ext.create( 'Ext.data.Store', {
data: [],
autoLoad: false,
proxy: {
type: 'rest',
url: '/somepath/theclass',
reader: {
type: 'json',
rootProperty: 'data',
totalProperty: 'totalCount'
},
writer: {
type: 'json'
},
}
} ),
...
// setting the data to be visualized
setValue: function(myObject) {
this.store.setData( myObject.data.items );
}
...
updateRecord: function(objectId, objectWithUpdateProperties) {
// do what with the store and/or proxy?
}
...
});
I display all entries in a table. The entries are not automatically loaded by the store but set from outside: setValue(myObject).
There is another store for initially loading the data. The data received is then splittet and forwarded in order not to have several requests.
I do get a nice visualized table whose entries are editable by the rowediting plugin.
Ok, so far the backgrounds.
When editing the table's data I run through some validations and gather more data via a modal dialog and then I have the data in order to send to the server by a call of updateRecord(objectId, objectWithUpdateProperties).
This sending is my problem. I do not know how to call/send a rest/put request which will be read by the server. (Receiving is not the problem, sending is).
I guess I somewhat need to trigger my store or the store's proxy. But how?
It is not that I can simply tell my object to save since I do have more data than just the changed object's properties.
Can anyone help me here?
I normally use Ext.Ajax to achieve that, like this:
updateRecord: function(objectId, objectWithUpdateProperties) {
Ext.Ajax.request({
url: 'YourUrl',
params: {
some_param: 'some_value',
object_id: objectId,
object_with_properties_param1: objectWithUpdateProperties.param1
},
success: function(response, opts) {
//Horay, Do something with the response
},
failure: function(response, opts) {
//Oh nooooo
}
});
}
Don't need to use Ajax.
You need to config proxy.api CRUD(C:create, R:read, U:Update. D:Delete) on RestProxy, from client side.
Also, store must have autoSync:true.
At server side, need to config a #RestController for each one of CRUD (with JSON-Java encoder for parameters like Jackson or equivalent), that will acept JSON data. Take into account, that you may send only modified field (store.proxy.writer.writeAllFields: false ->>> default) or just the full record (.writeAllFields:true) to server.
Here an example (inside store's constructor):
constructor: function(cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.apply({
autoLoad: true,
autoSync: true,
model: 'Test.model.Country',
proxy: {
type: 'rest',
api: {
create: 'country/create',
read: 'counrtry/list'
update: 'counrtry/update',
destroy: 'counrtry/destroy'
},
writer:{
writeAllFields : true
},
reader:{
root:'items',
totalProperty: 'rowCount'
}
}
}, cfg)]);
}
Extra note: For reading from server and load store automatically, just set store.autoLoad: true, and the corresponding #RestController method from server side. Take into account the store.reader params.

ExtJS 5 load existing store with local data

I am doing unit testing and would like to add dummy data to an existing store. In the function I am testing, I am calling a store:
var tripStore = Ext.getStore('Trips');
Normally, this store would have been populated by an Ajax call at a previous point. However, since I am testing I want to use dummy data and not rely on the back end. I realize I could rewrite the function to pass in the store, but I do not want to rewrite this for the sake of testing.
Bottom line, how do I add local data to a store that already exists but has no data in it? Furthermore, the back end is not available, so when I try store.load or store.reload it throws a 404 saying it cannot find the url rest/trip. I don't want it to try and call this url, but instead I want to add local data.
The model definition:
Ext.define('app.model.Trip', {
fields:[
{name: 'someField1', type: 'string'},
{name: 'someField2', type: 'string'},
{name: 'someField3', type: 'string'},
],
proxy: {
noCache: true,
url: 'rest/trip',
reader: {
type: 'json',
rootProperty: 'trips'
}
}
});
The (attempted) test script that is calling the url when I don't want it to, but only want it to add the local data:
var tripsStore = Ext.StoreManager.lookup('Trips');
tripsStore.load({
autoLoad: false,
addRecords: true,
proxy: {
data: localData,
},
callback: function(records, operation, success) {
if (success) {
debugger
} else {
debugger
}
}
})
Use ajax.SimManager. See example (open Details on the right-hand side, click on any of the Data tabs).

extjs using jsonp,Accessing data from remote url

with extjs,i m runnig the server from one system,giving the url in another system and i m using JSONP in extjs ver:4.02,when i check in response i m getting data in json format,when i try to print in console or Store im not getting..here is my extjs code...
<script type="text/javascript">
Ext.Ajax.cors = true;
Ext.Ajax.useDefaultXhrHeader = false;
Ext.define('User', {
extend: 'Ext.data.Model',
fields: ['empid', 'name', 'email']
});
var myStore = Ext.create('Ext.data.Store', {
model: 'User',
autoLoad:true,
proxy: {
type: 'jsonp',
// url : 'data/tagfamily.json',
url:'http://192.168.7.70:8080/palamanagement/user/getAllRecords',
},
listeners:{
'load':function( store, records, successful, eOpts ){
alert(records);
console.log(records);
}
}
});
You literally have to return something like the following:
someCallback({
users: [
{
id: 1,
name: "Ed Spencer",
email: "ed#sencha.com"
}
]
});
So you already have the JSON the way you need it; you just need your server response to wrap the JSON in the callback so that the JSONP proxy can execute and load your store with data.
Therefore, when handling the JSONP request, your server's script needs to recognize the "callback" param that is sent as a part of the request. It then needs to use the value of this param to wrap your JSON response.
Be sure to read the docs that both myself and Oguz have posted: they outline the requirement pretty well. But if you don't respond with a callback, you'll never get your standard JSON response to work with the JSONP proxy.
When you request from DOMAIN-A to DOMAIN-B, you should provide a call back function in proxy definition. The callback function will use in after request complete.
For instance, in Flickr REST service, there is jsoncallback parameter which we should give our function name in order to complete our request. In this way, our request url will be:
.../?jsoncallback=ourFunction
To be able to provide our function name, there is a property in ExtJS which is callbackKey.
Like so:
Ext.define('User', {
extend: 'Ext.data.Model',
fields: ['empid', 'name', 'email']
});
Ext.data.JsonP.request('http://api.flickr.com/services/feeds/photos_public.gne', {
callbackKey: 'jsoncallback',
callback: ourFunctionName
});
or
Ext.data.JsonP.request('http://api.flickr.com/services/feeds/photos_public.gne', {
callbackKey: 'jsoncallback',
callback: function(data) {
...
}
});
PS: I know, you will not find callback property in doc but just to be sure there is. Check ext-all-debug-w-comments.js file, line 108486
Flickr Callback Function
JsonP callbackKey

how to post array by store of sencha

I create one store and init it with some params with one array.when I execute the load function, the array parameter becomes a string '[object object]'
the code as follows:
store:
Ext.define('test.store.info',{
extend: 'Ext.data.Store',
config:{
model:'test.model.info',
proxy:{
type:'ajax',
url:'http://domain/path',
actionMethods:'POST'
}
}
});
model:
Ext.define('test.model.info',{
extend:'Ext.data.Model',
config:{
fields:[
'code',
'data'
]
}
})
use in controller:
var store = Ext.getStore('info');
params = {
t1:[{
f1:'aa'
},{
f2:'bb'
}],
t2:'ddd'
}
console.log(params)
store.load({
params:params
});
or I just use Ajax function instead load function , the result is the same.
Ext.Ajax.request({
url:'http://domain/path',
method:'post',
params:params,
});
I check the xhr within network of browser , it is a string as follows:
t1:[object Object]
t1:[object Object]
t2:ddd
when I check the server log, it shows :
t1:'[object Object]'
t1:'[object Object]'
t2:'ddd'
I found the solution , thank you
1, just use jsonData instead params during Ajax, like follows:
Ext.Ajax.request({
url: ajmd.util.version.getHost()+'/archimedes/update/selfInfo',
method:'post',
// params:params,
jsonData:params
});
2, or just encode the data before send
params.t1 = Ext.encode(params.t1);
If you name the parameter "foo[]", then it will encode it as a POST array making it easy to consume on the server side. Note the [] at the end.
var companies = [1,2,3];
Ext.Ajax.request({
url: '...',
method: "post",
params: {
'companies[]': companies,
},
success: function (response) {
console.log("done");
}
});

Model without a Store

I created a model which contains a proxy to load a single record and its takes no params. I don't want to use a store since I'll never have more then one record. I create an instance of the Model but can't figure out how to tell it to call and load the record from the server. This is the only example I could find, but I don't have an id to pass.
User.load(123, {
success: function(user) {
console.log("Loaded user 123: " + user.get('name'));
}
});
Also I'm making and ajax call and not a rest call in case that matters.
The load(id, [config]) is static and will return provide you with a new record instance. It uses the proxy that was set via setProxy(proxy) (also static). Per default it will send a read request with the params id: 123. The static method allows you to set some default callbacks within the optional config object. These callbacks are needed to get the instance of the loaded record (or the error).
How it works
// create a Model class
Ext.define('MyApp.User', {
extend: 'Ext.data.Model',
fields: [
{name: 'id', type: 'int'},
{name: 'name', type: 'string'}
]
});
// apply a proxy instance
MyApp.User.setProxy(/*YourAjaxProxy*/);
// prepare a handler
var cb = function(model, op) {
// log the new model instance
console.log(model);
};
// get a instance
MyApp.User.load(123, {
scope: this, // should be the scope of the callback (cb)
success: cb
});
Not what you need? Just comment...
Just make an Ajax request and store the result in a variable.
Ext.Ajax.request({
url: '/data/get',
method: 'GET',
params: {
requestID: 'XXXX',
connName: 'yyyy'
},
success: function (responseData) {
var countResult = Ext.decode(responseData.responseText); }
});

Resources