EXT JS Store's Proxy: readers and writers - javascript

In the documentation, i have found a store instantiated like this:
var store = Ext.create('Ext.data.Store', {
autoLoad: true,
model: "User",
proxy: {
type: 'ajax',
url : 'users.json',
reader: {
type: 'json',
root: 'users'
}
}
});
The proxy has one url config. I am particularly interested in the reader. The reader specifies the data exchange format (json) and the root ('users'). Now, in other words if the store is set up to be: autoLoad = true, then EXT JS will make an Ajax connection to the url specified in order to read. Now, how would i configure a writer for that same store above? Someone also tell me about this: if i configure a writer, would it use the same url as specified in the proxy? am still confused about writers and readers in context of the code i have showed above, you would help me use the above example to show readers and writer configs. Thank you.

Here is an example of a store with reader, writer and api in my App:
Ext.define('MyApp.store.Tasks', {
extend: 'Ext.data.Store',
model: 'MyApp.model.Task',
sorters : [{
property: 'idx',
direction: 'ASC'
}],
autoSync:true,
proxy:{
type: 'ajax',
reader: {
type: 'json',
root: 'data'
},
writer: {
type: 'json',
writeAllFields : false, //just send changed fields
allowSingle :false //always wrap in an array
// nameProperty: 'mapping'
},
api: {
// read:
create: 'task/bulkCreate.json',
update: 'task/bulkUpdate.json'
// destroy:
}
},
listeners : {
write: function(store, operation, opts){
console.log('wrote!');
//workaround to sync up store records with just completed operation
Ext.each(operation.records, function(record){
if (record.dirty) {
record.commit();
}
});
},
update:function(){
console.log('tasks store updated');
}
}
});

Actually you are correct - it will use the same url as for reader.
Proxy is a mediator between your model/store on a client and your server code on another side.
Readers are used for reading data and you could configure stuff like formatting, specify root etc. Writers are in charge of save/update requests to the server.
Check this article: http://edspencer.net/2011/02/proxies-extjs-4.html

Related

ExtJS GET action to store returns 500 in FireFox

I'm getting the strangest behavior from FireFox when loading data from a Web API GET request whereas other browsers do this perfectly. Here is what Fiddler can tell me when I use Firefox:
3817 500 HTTP localhost:52543 /api/Tasks/Get?_dc=1442848131483&page=1&start=0&limit=25 5 403 private application/xml; charset=utf-8 firefox:138020
Same action, other browser (Chrome):
3954 200 HTTP localhost:52543 /api/Tasks/Get?_dc=1442848159073&page=1&start=0&limit=25 1 508 no-cache; Expires: -1 application/json; charset=utf-8 chrome:2808
I'm unable to catch the error in the Application_Error, nor do I receive errors in the exception listener on the client-side, so I suspect something is going wrong between returning the result to the client and the client processing the results, but I have no clue at all where the problem might be situated.
Here is the store definition:
Ext.define('SchedulerApp.store.UnplannedTaskStore', {
extend: 'Ext.data.Store',
model: 'UnplannedTask',
autosync: false,
autoLoad: true,
proxy: {
type: 'rest',
api: {
read: '/api/Tasks/Get',
add: '/api/Tasks/Add',
update: '/api/Tasks/Update',
destroy: '/api/Tasks/Destroy'
},
actionMethods: {
create: 'POST',
read: 'GET',
update: 'POST',
destroy: 'POST'
},
reader: {
type: 'json',
rootProperty: 'data',
totalProperty: 'total'
},
writer: {
type: 'json',
writeAllFields: true
}
},
listeners: {
load: function (sender, node, records) {
},
exception: function (proxy, response, options) {
Ext.MessageBox.alert('Error', response.status + ": " + response.statusText);
}
}
});
and the model:
Ext.define('UnplannedTask', {
extend: 'Ext.data.Model',
fields: [
{ name: 'Importance', type: 'float' },
{ name: 'Category', type: 'string' },
{ name: 'TaskNo', type: 'float' }
]
});
This is what I have in the Web API:
[System.Web.Http.HttpGet]
public async Task<dynamic> Get(string page, string start, string limit)
{
// Get items from database with request information from the Kendo Grid Control
PagingResult<TaskViewModel> tasks = await this.Worker.GetPagedTasksAsync(int.Parse(page), int.Parse(limit), null, null);
// Map them to store objects
var convertedTasks = new SchedulerTasksViewModel()
{
total = tasks.Count,
data = tasks.Items.Select(x => new SchedulerTask()
{
Importance = x.Importance,
Category = x.Category,
TaskNo = x.TaskNumber
}).ToArray()
};
var response = Request.CreateResponse(HttpStatusCode.OK, convertedTasks);
return response;
}
Could it be a browser issue or am I missing something on the server side?
Try adding this header to your proxy:
headers: {'Content-Type': "application/json" }
I would like to elaborate a bit. The error is thrown by the XML serializer; you don't see the details because IIS does not send them to the front.
I would recommend to modify all your API calls such that they work with XML as well - even if your front-end does not use XML. It's far easier to debug if you can just open API calls in new browser tabs and the XML serializer does not mask code errors with serialization errors.
To see the error message, you would have to allow your development IIS to bring errors to the front:
Open the IIS7 manager
Select the Website and on its features view, double click on “Error Pages”.
Right click and select the “Edit Feature Settings…” or select the same from the Actions pane (in the right hand side)
Select the “Detailed errors” radio button and click on OK
(Source)
My best guess is that you just have to decorate some types or properties with [DataContract], [DataContractAttribute] or [DataMemberAttribute]. The error message will tell you which ones and how to decorate.
Another thing entirely: If you use more than one Ajax request, I'd recommend to define an override on the Ajax proxy. That way you can't forget one:
Ext.define("MyApp.override.Ajax", {
override:'Ext.data.proxy.Ajax',
headers:{'Accept':'application/json'}
});

how load data from Json to Json in Extjs

in my case, i want, if click the button "drilldown" chart load new data from another Json. This is my Store
Ext.define('DWP3.store.konten.Coba', {
extend: 'Ext.data.Store',
alias: 'store.coba',
storeId: 'coba',
uses: [
'Ext.data.Store'
],
fields: [
{name: 'periode'},
{name: 'Teknik'},
],
proxy: {
type: 'ajax',
url : 'resources/data/load2.php',
reader: {
type: 'json',
rootProperty: 'view_sum1'
}
},
autoLoad: true,
});
}
i want load the new data also from json which converted from mySQL. i want load this one :
newData : function(){
var store = Ext.create('Ext.data.Store', {
fields: [
{name: 'periode'},
{name: 'prodi'},
],
proxy: {
type: 'ajax',
url : 'resources/data/load3.php', //from another load in php
reader: {
type: 'json',
rootProperty: 'view_sum2' // another root
}
},
autoLoad: true,
});
return store;
}
i call the function like this in my chart.js:
{
text:'Test',
handler:function(){
this.down('cartesian').getStore().newData();
}
}
in this case i want if click the button my store load new data but from another Json which converted from mySQL. it is possible to do that?or do you have any solution from my case?
I would advice you to declare your 2nd store the same way you did with the first one. And simply load it inside the handler of your drilldown :
handler : function() {
Ext.getStore('your new store ID').load();
}
But I'm not really sure what you really want, your question isn't clear to me.

Access the Google api using Extjs 4.2

I have tried to access the following url using Extjs sencha. Data not loaded on run time. When i try to access the url on browser i am able to see the data
https://maps.googleapis.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&sensor=true&key=API_KEY.
I am newbie for Extjs.I know i am trying to load the cross domain data.But i dont know how to achieve this. Please somebody help me
Ext.define('MyApp.store.MyJsonStore', {
extend: 'Ext.data.Store',
requires: [
'MyApp.model.MyModel',
'Ext.data.proxy.Ajax',
'Ext.data.reader.Json'
],
constructor: function(cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.apply({
model: 'MyApp.model.MyModel',
storeId: 'MyJsonStore',
proxy: {
type: 'ajax',
url: 'https://maps.googleapis.com/maps/api/geocode/json?address=Barcroft + Plaza +Apartments ,+22041&sensor=true&key=API_KEY',
reader: {
type: 'json'
}
},
listeners: {
load: {
fn: me.onJsonstoreLoad,
scope: me
}
}
}, cfg)]);
},
onJsonstoreLoad: function(store, records, successful, eOpts) {
Ext.MessageBox.show('Loaded');
}
});
Instead of Ajax proxy i have tried jsonp also.If i use jsonp then i am getting uncaught syntaxerror unexpected token .I have searched so many blogs, forums everybody talked about adding callback but i am calling third party api
I have tried following code for jsonp.I Have tried both ways like with and without callback key
proxy: {
type: 'jsonp',
url: 'https://maps.googleapis.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&sensor=true&key=API_KEY',
callbackKey: 'Mycallback',
reader: {
type: 'json',
root: 'results'
}

ExtJS store initialization using json fails

I have a store like this:
Ext.define('app.store.System', {
extend : 'Ext.data.Store',
model : 'app.model.System',
autoLoad: true,
autoSync: true,
proxy: {
type: 'rest',
format: 'json',
url: '/application/appinfo',
method : "GET",
reader: {
type: 'json',
root: 'System'
},
writer: {
root: 'System',
allowSingle: false
}
}
});
and I have a service endpoint to handle requests that match /application with this method:
#GET
#Path("/{sysinfo}")
public List<SystemInfo> getSystemInfo() {
if(sysinfo == null){
sysinfo = new SystemInfo();
...initialize
}
List<SystemInfo> resultList = new ArrayList<SystemInfo>();
resultList.add(sysinfo);
return resultList;
}
and it seemed to work... when I tried to to reach localhost:port/application/sysinfo.json I got this:
{ [{"address":"...","feeds":["feed1","feed2"] } ] }
which seems correct but when I try to read the data from the store in the view's init method:
var store = Ext.StoreManager.lookup('System');
var data = [];
store.each(function(record) {
data.push(record.getData());
console.log("record data: ");
console.log(record.getData());
});
console.log(data[0]);
It says that it's undefined as if the store was empty. I tried it with the debugger and i found that the getSystemInfo() was called after the view's initcomponent but unfortunately I don't know why that is or how to solve it. Any ideas?
Thanks for your time.
Have you tried loading your store first?
var store = Ext.StoreManager.lookup('System');
var data = [];
store.load({
callback: function(storeVar, records, successful) {
Ext.each(records, function(record) {
data.push(record.getData());
console.log("record data: ");
console.log(record.getData());
});
}
console.log(data[0]);
});
And what boris says is true, you need to define your root property in the returned JSON.
If you're using chrome or firefox you can also check which network call is made, and what it returns (JSON data...).
Try this:
return new { success: true, System = resultList};

Extjs4: TreeStore with method POST

I have a Ext.tree.Panel and define in it I have a store. I want to be able to update the store via ajax along with POST params.
Here is my tree definition:
var mytree = Ext.create('Ext.tree.Panel',{
rootVisible:false,
store:Ext.create('Ext.data.TreeStore', {
root:{
id:'rootnode',
nodeType:'async'
},
proxy:{
method:'post',
type:'ajax',
url:'myurl'
}
})
});
And I try and reload the store as follows:
mytree.store.load({params:{search_string='value'}})
But the store attempts to reload with the params as GET Parameters.
Some help would be greatly appreciated. The ExtJS 4 Docs arent great at the moment (in my opinion)
There is actionMethods parameter in proxy to specify method of requests: http://dev.sencha.com/deploy/ext-4.0.0/docs/api/Ext.data.proxy.Ajax.html
proxy:{
actionMethods: {
create: 'POST',
destroy: 'DELETE',
read: 'POST',
update: 'POST'
},
type:'ajax',
url:'myurl'
}

Categories