The URL of an ajax proxy - Ext JS - extjs

I have a couple of questions about the url field of an ajax proxy, and Ext.Ajax.request
I'm getting a JSON response from an Ext.Ajax.request, and sending that data to a store. (I'm also trying to use the pagingToolbar, which is highly uncooperative at the moment)
Anyhow, the paging only seems to slightly work when I use an ajax proxy, however I'm not sure what to put in as the URL. Currently it's url: ''
var store = Ext.create('Ext.data.Store', {
storeId : 'resultsetstore',
autoLoad : false,
pageSize : itemsPerPage,
fields: [
{name : 'id', type : 'auto'},
{name : 'name', type : 'auto'},
{name : 'description', type : 'auto'}
],
proxy: {
type : 'ajax',
url : '???',
reader: {
type : 'json',
root : 'elements'
}
}
});
It seems the url reads data from a .json file in a specific directory (i.e. url: 'myData/data.json'), but there isn't any file like that to read from, as my response is coming back as a JSON Object.
And here is my request/response, which I parse and send to my store:
var request = Ext.Ajax.request({
url : 'MCApp', //here I specify the Servlet to be read from
jsonData : searchquery, //A JSON Object
params:{
start:0,
limit: itemsPerPage
},
success : function(response) {
mainresponse = response.responseText;
//etc.
}
Is having a separate request redundant?
Could I accomplish this within my store alone (passing my searchquery as a parameter to the server and all that jazz)?
I apologize for this jumbled question in advance!
Cheers

You can use a memory proxy and set the store data with the data property, but I don't recommend that.
If I where you I would forget the ajax request and start take advantage of the store's proxy.
Here's an example
var store = Ext.create('Ext.data.Store', {
storeId: 'resultsetstore',
autoLoad: false,
pageSize: 20,
fields: ['id','name','description'],
proxy: {
type: 'ajax',
url: 'urlToTheServlet', //here I specify the Servlet to be read from
extraParams: {
searchquery: 'Test'
}, //A String Object
reader: {
type: 'json',
root: 'elements'
}
}
});
store.load();
note that the start, limit are dealt with in the background. You don't have to set them manually. You can set a pageSize but it has it's own default, so it's not required.
This is what your data is expected to look like:
{
"elements": [
{
"id": 1,
"name": "John",
"description": "Project Manager"
},
{
"id": 2,
"name": "Marie",
"description": "Developer"
},
{
"id": 3,
"name": "Tom",
"description": "Technical Lead"
}
]
}
UPDATE: Passing an object as payload to the proxy
I had the same issue and I couldn't find an out of the box solution so I wrote my own proxy to resolve this.
Ext.define('BCS.data.proxy.AjaxWithPayload', {
extend: 'Ext.data.proxy.Ajax' ,
alias: 'proxy.ajaxwithpayload',
actionMethods: {
create: "POST",
destroy: "POST",
read: "POST",
update: "POST"
},
buildRequest: function(operation) {
var me = this,
request = me.callParent([operation]);
request.jsonData = me.jsonData;
return request;
}
});
Now you can do this:
var store = Ext.create('Ext.data.Store', {
storeId: 'resultsetstore',
autoLoad: false,
pageSize: 20,
fields: ['id','name','description'],
proxy: {
type: 'ajaxwithpayload',
url: 'urlToTheServlet', //here I specify the Servlet to be read from
jsonData : YOUR_OBJECT
reader: {
type: 'json',
root: 'elements'
}
}
});

I prefer to keep each method in a separated endpoint:
proxy: {
type: 'ajax',
reader: {
type: 'json'
},
api: {
read: 'getCenarioTreeNode', // To request a node children (expand a node)
create: 'createCenarioTreeNode', // When you insert a node
update: 'updateCenarioTreeNode', // When you change a node attribute
destroy: 'destroyCenarioTreeNode' // When you delete a node
},
writer: {
type:'json',
encode:true,
rootProperty:'data'
}
},

Related

ExtJS store filter is being sent not in full

I've a store syncronized with remote db model. I need to apply remote filtering. Problem is that if i set a filter in config options the filter is being sent (on load or on sync) but not fully.
Store:
var RegularItemsStore=Ext.create("appMain.Store.UniversalStore",{
model: 'OrderModel',
modelName:'Order2',
autoSync: true,
filters: [{ "property" : "storeId", "value": 0 , "type": "numeric", "operator": "="},
});
in Http ajax request this filter is passed with ONLY "property" : "storeId", "value": 0, the "type": "numeric", "operator": "=" are missed; in web-dev tools:
Query String Parameters
r:backend/index
Table:Order2
log:0
...
filter:[{"property":"storeId","value":0}]
while if i set filter on the proxy pertaining to store, the filter is passed to server unchanged (in right way):
Proxy config:
this.proxy =
{
url: "index.php?r=backend/index&Table=" + this.modelName + this.params,
reader: {
root: "result.data",
totalProperty: "result.count",
type: "json",
metaProperty: 'myMetaData', // config for metaData:
},
actionMethods: {
read: 'GET', update: 'POST'
},
...
};
and filter applying:
Ext.each(ItemStoreArray, function(store){
var filter = [ { property: 'contractorId', value: ContractorSelectedId , operator: '=', type: 'numeric' }, { property: 'userId', value: UserId , operator: '=', type: 'numeric' }];
store.getProxy().setExtraParam('filter' , Ext.JSON.encode(filter) );
store.load(); //console.dir(store);
});
How to resolve it? Should i set a permanent filter on proxy in the store init, how?
Update
As followed Alexander's recommendation i've overriden the proxy's config parameter that solved the issue:
encodeFilters: function(filters) {
var min = [],
length = filters.length,
i = 0;
for (; i < length; i++) {
min[i] = {
property: filters[i].property,
value : filters[i].value,
operator : filters[i].operator, // added
type : filters[i].type, // added
};
}
return this.applyEncoding(min);
},
You can override encodeFilters: function(filters) in the proxy you use.
For the default implementation have a look at src/data/proxy/Server.js.

Sencha Touch 2.3 and Extjs 4.2

I am using Sencha Touch 2.3 and Extjs 4.2
Issue: Handle multiple root nodes JSON response(from single response) in multiple stores.
{
total:
[
{
exp_amount_tot: "71962.00",
income_amount_tot: "462129.00"
}
],
data:
[
{
id: "1",
userid: "2",
name: "Any",
notes: "",
},
]
}
I need to save the above response into two different stores.
1. dataStore rootproperty:"data"
2. summaryStore rootProperty: "total"
Please help me to fix this issue.
Store:
proxy: {
type: "ajax",
api: {
create: "http://localhost/api/getAccounts.php/create",
read: "http://localhost/api/getAccounts.php/getall",
update: "http://localhost/api/getAccounts.php/update",
},
reader: {
type: "json",
successProperty: 'success',
rootProperty: 'data',
messageProperty: 'message'
},
},
you can create 2 different stores with "data" & "total" root properties respectively and use the store.add() method to add the data to individual store.

Sencha: Use store in other view

I have a store, which is created in a controller when login is successful. The code looks like this:
controller is login.js
//////////// create a JSONstore and load companies into it //////////////
var companies_data = new Ext.data.JsonReader({}, [ 'companyame']);
var storeCompanies = new Ext.data.JsonStore({
storeId: 'storeCompanies',
proxy: new Ext.data.HttpProxy({
type: 'GET',
url: url+'dashboard/?Uid='+uid+'&Ude='+ude,
reader: {
type: 'json',
root: 'root',
totalProperty: 'total'
},
headers: {
'Accept' : 'application/json;application/x-www-form-urlencoded',
'Content-Type' : 'application/x-www-form-urlencoded',
},
params: {
Uid: localStorage.uid,
Ude: localStorage.ude,
},
}),
reader: companies_data,
root: 'd',
type: 'localstorage',
autoLoad : true,
id: 'company_Id',
scope : this,
fields: ['companyname']
});
The code is a function, which is called on successful login and values are passed to it.
This works fine for as is, and the store is available to the login view
I need the store to be available to my mainview.
In my login.js controller, I have referred to the mainview like this:
Ext.define('axis3.controller.Login', {
extend: 'Ext.app.Controller',
config: {
refs: {
loginView: loginview,
mainView: 'mainview',
chartView: 'chartview'
},
control: {
loginView: {
signInCommand: 'onSignInCommand'
},
mainMenuView: {
onSignOffCommand: 'onSignOffCommand'
}
}
},
but this does not seem to help.
When I use the following in my mainview
var companyStore = Ext.getStore('storeCompanies'); //
console.log('1-Number : ' + companyStore.getCount()); // Using getCount method.
var anotherCompany = { companyname: 'North Wells'};
companyStore.add(anotherCompany); //
console.log('2-Number : ' + companyStore.getCount()); // Using getCount method.
//////////////
Ext.define('axis3.view.Main', {
extend: 'Ext.form.Panel',
requires: ['Ext.TitleBar','Ext.data.Store'],
alias: 'widget.mainview',......................
I get this error:
TypeError: 'undefined' is not an object (evaluating
'companyStore.getCount')
How can I use my store in a different view?
Give storeId, try like this
var storeCompanies = Ext.create("Ext.data.JsonStore",{
storeId: 'storeCompanies', // add this line
proxy: new Ext.data.HttpProxy({
type: 'GET',
url: url+'dashboard/?Uid='+uid+'&Ude='+ude,
reader: {
type: 'json',
root: 'root',
totalProperty: 'total'
},
headers: {
'Accept' : 'application/json;application/x-www-form-urlencoded',
'Content-Type' : 'application/x-www-form-urlencoded',
},
params: {
Uid: localStorage.uid,
Ude: localStorage.ude,
},
}),
reader: companies_data,
root: 'd',
type: 'localstorage',
autoLoad : true,
id: 'company_Id',
scope : this,
fields: ['companyname']
});
Now try again with Ext.getStore('storeCompanies');
If have figured out the problem. The view is trying to use the store before it exists. The store is only created when a user logs in.
The solution I have decided to use is to create an empty store and then add data to it on successful login.
var anotherCompany = {companyname: 'Keep Groom'};
companiesStore2.add(anotherCompany); // Use the add function to add records or model instances.
This seems to work

How to load the tree panel tree store with Ajax response

How to load the tree panel tree store with Ajax response.
How to load the tree panel tree store with Ajax response json.
i can load it locally , i.e. if i have the json file locally available then i can load it through configured proxy by using treeStore.load() method.
But now if i have the data from a Ajax response then how can i do that?
Model :
Ext.define('dimExpModel', {
extend : 'Ext.data.Model',
fields : [
{
name: 'memberName'
},
{
name: 'memberCode'
},
{
name: 'dimension'
}
]
});
Store :
var dimExpStore = Ext.create('Ext.data.TreeStore',{
storeId:'dimExpStore',
model:dimExpModel,
proxy: {
type: 'memory',
reader: {
type: 'json'
}
}
});
Tree Panel :
{
"xtype": "treepanel",
"height": 250,
"id": "treePanel",
"width":400,
"title":"My Tree Panel",
"store": "dimExpStore",
"displayField":"memberName",
"useArrows":true,
"viewConfig": {
}
};
Any help is appreciated.
T would do it like this:
{
"xtype": "treepanel",
"height": 250,
"id": "treePanel",
"width":400,
"title":"My Tree Panel",
"rootVisible":false,
"store":{autoLoad:true,"fields":[{"name":"id",type:"string"},
{"name":"memberName","type":"string"},{"name":"memberCode","type":"string"},
{"name":"memberCode","type":"dimension"}],
proxy:{type:'ajax',url:'json.php'},root:{text:"Members","id":"src","expanded":true}}
"displayField":"memberName",
"useArrows":true,
"viewConfig": {
}
};
In my example json.php returs the desired json in a correct form.
Edit
Take a look at "id" param inside root block. Each time when you click on tree nodes containing children, at the server side you should form a correct response depending on that "id" which is actually id_parent of all those children nodes.
You need to define your store proxy as ajax and call store.load()
var dimExpStore = Ext.create('Ext.data.TreeStore',{
storeId:'dimExpStore',
model:dimExpModel,
proxy: {
type: 'ajax',
url : 'users.json',
reader: {
type: 'json',
root: 'records',
totalProperty: 'recordCount',
successProperty: 'success'
}
}
});

Ext.data.LocalStorage not working on Offline Mode

Im now studying Sencha Touch 2 and doing some Research on Ext.data.LocalStorage that can be use in Offline Mode.
I tried to follow this turorial
Sencha Touch 2 Local Storage
and just updated the code from Github - RobK/SenchaTouch2-LocalStorageExample or riyaadmiller/LocalStorage and modified Store url using my own WCF Rest
but i cant get LocalStorage working on offline mode.I have no issue on running the app Online. I also tried to debug it on Chrome developer tool but LocalStorage always get 0 data. I used Chrome/Safari Browser and also build the apps as Android using Phonegap build and still not working.
Did I miss something?
Does anyone can provide the details to deal with this Issue.
Below is my code:
Store:
Ext.define('Local.store.News', {
extend:'Ext.data.Store',
config:{
model: 'Local.model.Online',
proxy:
{
type: 'ajax',
extraParams: { //set your parameters here
LookupType: "Phone",
LookupName: ""
},
url: 'MY WCF REST URL',
headers: {
'Content-Type': 'application/json; charset=utf-8'
},
reader:
{
type: 'json'
, totalProperty: "total"
},
writer: { //Use to pass your parameters to WCF
encodeRequest: true,
type: 'json'
}
},
autoLoad: true
}
});
Offline Model:
Ext.define('Local.model.Offline', {
extend: 'Ext.data.Model',
config: {
idProperty: "ID", //erm, primary key
fields: [
{ name: "ID", type: "integer" }, //need an id field else model.phantom won't work correctly
{ name: "LookupName", type: "string" },
{ name: "LookupDescription", type: "string" }
],
identifier:'uuid', // IMPORTANT, needed to avoid console warnings!
proxy: {
type: 'localstorage',
id : 'news'
}
}
});
Online Model:
Ext.define('Local.model.Online', {
extend: 'Ext.data.Model',
config: {
idProperty: "ID", //erm, primary key
fields: [
{ name: "ID", type: "integer" }, //need an id field else model.phantom won't work correctly
{ name: "Name", type: "string" },
{ name: "Description", type: "string" }
]
}
});
Controller:
Ext.define('Local.controller.Core', {
extend : 'Ext.app.Controller',
config : {
refs : {
newsList : '#newsList'
}
},
/**
* Sencha Touch always calls this function as part of the bootstrap process
*/
init : function () {
var onlineStore = Ext.getStore('News'),
localStore = Ext.create('Ext.data.Store', { storeid: "LocalNews",
model: "Local.model.Offline"
}),
me = this;
localStore.load();
/*
* When app is online, store all the records to HTML5 local storage.
* This will be used as a fallback if app is offline more
*/
onlineStore.on('refresh', function (store, records) {
// Get rid of old records, so store can be repopulated with latest details
localStore.getProxy().clear();
store.each(function(record) {
var rec = {
name : record.data.name + ' (from localStorage)' // in a real app you would not update a real field like this!
};
localStore.add(rec);
localStore.sync();
});
});
/*
* If app is offline a Proxy exception will be thrown. If that happens then use
* the fallback / local stoage store instead
*/
onlineStore.getProxy().on('exception', function () {
me.getNewsList().setStore(localStore); //rebind the view to the local store
localStore.load(); // This causes the "loading" mask to disappear
Ext.Msg.alert('Notice', 'You are in offline mode', Ext.emptyFn); //alert the user that they are in offline mode
});
}
});
View:
Ext.define('Local.view.Main', {
extend : 'Ext.List',
config : {
id : 'newsList',
store : 'News',
disableSelection : false,
itemTpl : Ext.create('Ext.XTemplate',
'{Name}-{Description}'
),
items : {
docked : 'top',
xtype : 'titlebar',
title : 'Local Storage List'
}
}
});
Thanks and Regards
1) First of all when you creating record and adding into store, the record fields should match the model fields of that store.
Here you creating record with field name, but Local.model.Offline didn't name field
var rec = {
name : record.data.name + ' (from localStorage)'
};
This is what you need to do within refresh
localStore.getProxy().clear();
// Also remove all existing records from store before adding
localStore.removeAll();
store.each(function(record) {
console.log(record);
var rec = {
ID : record.data.ID,
LookupName : record.data.Name + ' (from localStorage)',
LookupDescription : record.data.Description
};
localStore.add(rec);
});
// Don't sync every time you add record, sync when you finished adding records
localStore.sync();
2) If specify idProperty in model which is using localStorage, then record will not be added into localStorage.
Model
Ext.define('Local.model.Offline', {
extend: 'Ext.data.Model',
config: {
// idProperty removed
fields: [
{ name: "ID", type: "integer" }, //need an id field else model.phantom won't work correctly
{ name: "LookupName", type: "string" },
{ name: "LookupDescription", type: "string" }
],
identifier:'uuid', // IMPORTANT, needed to avoid console warnings!
proxy: {
type: 'localstorage',
id : 'news'
}
}
});

Resources