loading data from a json - arrays

i have data available i want to load like this:
{
"success": true,
"message": null,
"total": null,
"data": [{
"clockTypes": ["_12", "_24"],
"speedTypes": ["MPH", "KMPH"],
"scheduleTypes": ["DEFAULT", "AUTO"]
}]}
i am normaly load the data like this
Ext.define('MyApp.store.comboTimezone', {
extend: 'Ext.data.Store',
constructor: function(cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.apply({
autoLoad: true,
storeId: 'MyJsonStore5',
proxy: {
type: 'ajax',
url: 'json/timezone.json',
reader: {
type: 'json',
root: 'data'
}
}
}, cfg)]);
}});
now do i get the clocktypes as one record in my combobox. how can i get two records: _12 and _24 in my combobox?

Your root should be... data.clockTypes I -think- ( though I'm not really sure if that would work. )
Hijacking that ajax call to load the data is a bit awkward, since thats not really the right format for the store to consume( is it? )
Ideally you want...
{
"success": true,
"message": null,
"total": null,
"data": [{
name: "_12", name:"_24"]
}]}
constructor: function(cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.apply({
autoLoad: true,
storeId: 'MyJsonStore5',
valueField:'name',
displayField:'name',
proxy: {
type: 'ajax',
url: 'json/timezone.json',
reader: {
type: 'json',
root: 'data'
}
}
}, cfg)]);
}});
Though this does mean you end up with more ajax calls. Alternatively, if you've got your heart set on populating 3 comboboxes (I'm kinda guessing that's what your trying to do ) from 1 ajax call, then you need to generate the stores dynamically based off the data from
an Ext.request()
However if you cant mess with the data, then we can...
Ext.define('MyApp.store.comboTimezone', {
extend: 'Ext.data.Store',
constructor: function(cfg) {
var me = this;
cfg = cfg || {};
Ext.define('TZ', extend: 'Ext.data.Model',
fields: [{
name: 'name'
}])
me.callParent([Ext.apply({
autoLoad: true,
model: 'TZ',
storeId: 'MyJsonStore5',
proxy: {
type: 'ajax',
url: 'json/timezone.json',
reader: {
type: 'json',
root: 'data'
}
}
}, cfg)]);
//hacky, but works i guess
Ext.Ajax.request({
url: 'my.json',
success: function(response) {
var text = response.responseText;
var json = Ext.JSON.decode(text);
for(var i =0);i<json.data.lenght();i++;){
Ext.data.StoreManager.lookup('MyJsonStore5').add(Ext.create('TZ',{name:json.data[i]}))
}
}
});
}
});
*barrring typos which create bugs.
Basically you call the url, get the data as raw json, and then process it into a format that your store can read.
It's a bit of a hack unfortunately.

Related

ExtJS — How to load store data manually after ajax call?

I rewrite my working Fiddle from ajax proxy type to memory. I'm trying to load memory store data manually:
// app/model/Employees.js file
Ext.define('Fiddle.model.Employees', {
extend: 'Ext.data.Model',
entityName: 'Employees',
fields: [
{
name: 'profile_pic'
},
{
type: 'int',
name: 'age'
},
{
type: 'string',
name: 'last',
mapping: 'name.last'
},
{
type: 'string',
name: 'first',
mapping: 'name.first'
},
{
type: 'string',
name: 'email'
}
],
proxy: {
type: 'memory',
reader: {
type: 'json',
rootProperty: 'items',
totalProperty: 'total',
successProperty: ''
}
}
});
// app/store/Employees.js file
Ext.define('Fiddle.store.Employees', {
extend: 'Ext.data.Store',
pageSize: 30, // items per page
alias: 'store.employees',
model: 'Fiddle.model.Employees',
});
//app.js fule - launch() function
var store = Ext.create('Fiddle.store.Employees');
console.log(store);
Ext.Ajax.request({
url: 'mates.json',
success: function(resp) {
var result = resp.responseText;
console.log(result);
// store.loadRawData(result);
store.loadData(result);
console.log(store);
console.log(store.getAt(0));
},
});
As result I have 3386 records in store, every symbol in my json file. And what I see in console as first record:
What I'm doing wrong?
And where I need to put proxy lines - in model or in store?
responseText is a string, which contains the serialized JSON data. You have to deserialize it into an object before you can use loadRawData to load the object through the model converters into the store:
var result = Ext.decode(resp.responseText);
store.loadRawData(result);
loadData and loadRawData differ in that loadData does not call the converters on the model. loadRawData is equivalent to what the ajax proxy does, loadData is not.
Did it in this way:
//in Grid panel js file
listeners: {
afterrender: function(grid, evt) {
var myStore = grid.getStore();
Ext.Ajax.request({
url: 'mates.json',
success: function(resp) {
var result = Ext.decode(resp.responseText);
myStore.getProxy().data = result;
myStore.load();
},
});
}
}
In store autoLoad: true must be disabled. This way of loading instead of store.loadRawData(result); shows the correct number of records in the pagingtoolbar.

How to load store via POST request

I need to load store via cross domain POST request
Ext.define('MyDesktop.desktop.store.DesktopShortcutStore', {
extend: 'Ext.data.Store',
requires: [
'MyDesktop.desktop.model.DesktopShortcutModel'
],
constructor: function(cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.apply({
storeId: 'DesktopShortcutStore',
model: 'MyDesktop.desktop.model.DesktopShortcutModel',
autoLoad: false,
proxy: {
type: 'ajax',
url: getApiUrl() + 'account/desktop-shortcuts-list',
cors: true,
reader: {
type: 'json',
rootProperty: 'items',
successProperty: 'success'
},
paramsAsJson: true,
actionMethods: {
read: 'POST'
},
extraParams: {
fff: 'zzz'
}
}
}, cfg)]);
}
});
But I have OPTIONS request with no "fff" param.
Cross domain via jQuery is working correctly.
Using
Ext.Ajax.useDefaultXhrHeader = false;
Ext.Ajax.cors = true;
Is not helps.
I cannot find any information in docs.
This should be the easiest solution. Loading a store directly via a proxy and POST might require a few overrides, not sure it's worth the effort (needs more investigation).
var store = ...;
Ext.Ajax.request({
method: 'POST',
url: '...',
withCredentials: true, // for identity cookies
success: function(response) {
// given json array is returned
var data = Ext.decode(response.responseText);
Ext.each(data, function(r) {
store.add(r);
});
}
});

ExtJS TreeStore is empty if I load store by manually

Model
Ext.define('MyDesktop.model.mail.MailFoldersModel', {
extend: 'Ext.data.Model',
requires: [
'Ext.data.field.String'
],
fields: [
{
type: 'string',
name: 'id'
},
{
type: 'string',
name: 'idParent'
},
{
type: 'string',
name: 'text'
}
]
});
My TreeStore
Ext.define('MyDesktop.store.mail.MailFoldersStore', {
extend: 'Ext.data.TreeStore',
requires: [
'MyDesktop.model.mail.MailFoldersModel'
],
constructor: function(cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.apply({
storeId: 'MailFoldersStore',
model: 'MyDesktop.model.mail.MailFoldersModel',
autoLoad: true,
proxy: {
type: 'ajax',
url: 'http://url/mail/folders',
reader: {
type: 'json',
rootProperty: 'items',
successProperty: 'success'
}
},
root: {
text: 'root',
iconCls: 'mail-folders-owner'
}
}, cfg)]);
}
});
Store is autoloaded, all works correctly, store contains 11 records.
var MailFoldersStore = Ext.create('MyDesktop.store.mail.MailFoldersStore', {
storeId: 'MailFoldersStore'
});
If I set autoLoad to false and trying to load by manually - store is empty, 0 records.
var MailFoldersStore = Ext.create('MyDesktop.store.mail.MailFoldersStore', {
storeId: 'MailFoldersStore'
});
MailFoldersStore.load({
callback : function(records, operation, success) {
console.log(records);
}
});
What can be a reason for this behaviour?
I also has same problem. I am using Extjs 5.1. After googling I found one complex solution which needs us to modify the framework.
See the below link if it can help you.
http://www.sencha.com/forum/showthread.php?154823-listeners-quot-exception-quot-in-proxy.ajax-on-TreeStore-do-not-work

sencha touch: change extraParams when it loaded

I should load date from server dynamically,
however, I have no idea how to change get parameters.
Here is my code.
I want to load store when the view is loaded, but the store get data from server
when the app is loaded. I need to change param according to user's input data.
[Store]
Ext.define('APP.store.MyTestStore', {
extend: 'Ext.data.Store',
requires: [
'APP.model.MyModel',
],
config: {
model: 'APP.model.MyModel',
autoLoad: false,
storeId : 'MyTestStore',
proxy: {
type: 'jsonp',
method: 'GET',
// extraParams: {
// man: '',
// },
url: 'http://test.com/api/test/',
reader: {
type: 'json',
rootProperty: 'apiList'
}
}
},
});
[VIEW]
Ext.define('APP.view.MyListView', {
extend: 'Ext.navigation.View',
xtype: 'applistview',
requires: [
'Ext.Panel',
'APP.view.TopMenu',
'APP.view.TestListView',
'APP.config.Runtime',
],
fullscreen: true,
config: {
navigationBar: false,
fullscreen: true,
items: [
{ // Top Menu
xtype: 'topmenu',
},
{ // Main Menu
xtype: 'tlist',
itemId: 'myList',
store: 'MyTestStore',
},
{ // Bottom Banner
xtype: 'bottombanner',
},
]
},
initialize: function(){
var test = Ext.getStore('MyTestStore').load({extraParams:{man:'test'}});
console.log(test);
}
});
You can do this in two ways,
App default extra param set to 123
Ext.define('APP.store.MyTestStore', {
extend: 'Ext.data.Store',
requires: [
'APP.model.MyModel'
],
config: {
model: 'APP.model.MyModel',
autoLoad: false,
storeId : 'MyTestStore',
proxy: {
type: 'jsonp',
method: 'GET',
extraParams: {
man: '123'
},
url: 'http://test.com/api/test/',
reader: {
type: 'json',
rootProperty: 'apiList'
}
}
}
});
When loading the store you can change extra param like the following way
initialize: function(){
var test = Ext.getStore('MyTestStore').getProxy().getExtraParams().man= '567'
Ext.getStore('MyTestStore').load();
console.log(test);
}
In Another way you can change proxy url without setting extra param
initialize: function(){
var url = 'http://test.com/api/test/'; // your store proxy url
var modified = url+'parameter you get from user'
Ext.getStore('MyTestStore').getProxy().setUrl(modified);
Ext.getStore('MyTestStore').load();
console.log(test);
}

Accessing a store from another store - Sencha Touch

I'm trying to create a store and inside access the data from another store to construct the proxy url.
Something like this:
Ext.define('MyApp.store.Post',{
extend:'Ext.data.Store',
config: {
model: 'MyApp.model.Post',
proxy: {
type: 'ajax',
url: 'http://mywebsite.com/get?userid=' + Ext.getStore('UserData').getAt(0).data.userid,
reader: {
type: 'json'
}
}
}
});
So, I'm basically trying to get the userid from another store to be able to construct the correct url.
This doesn't work, I get:
Uncaught TypeError: Object #<Object> has no method 'getStore'
What is the correct way to do this?
EDIT: Okay I put in a dummy URL and trying to change it with a listener, this is my store now:
Ext.define('MyApp.store.Post',{ extend:'Ext.data.Store',
config: {
fields: [
'title', 'link', 'author', 'contentSnippet', 'content'
],
proxy: {
type: 'jsonp',
url: 'https://ajax.googleapis.com/ajax/services/feed/load?v=1.0&q=http://feeds.feedburner.com/SenchaBlog',
reader: {
type: 'json',
rootProperty: 'responseData.feed.entries'
}
},
listeners: [
{
beforeload: function(){
console.log("store loaded"); //I DON'T SEE THIS IN CONSOLE
return true;
}
}
]
},
});
Basically you did nothing wrong, but the reason is sencha touch uses asynchronous loading and it seems that Ext.getStore() is not instantiated at the time your store is defined.
Let's try this method instead:
First, add a listener for beforeload event inside your store config:
Ext.define('MyApp.store.Post',{
extend:'Ext.data.Store',
config: {
model: 'MyApp.model.Post',
proxy: {
type: 'ajax',
//url: you don't even need to set url config here, simply ignore it
reader: {
type: 'json'
}
}
},
listeners: [
{
fn: 'setUrl',
event: 'beforeload'
}
]
});
then declare a function like this, in the same file:
setUrl: function(){
this.getProxy().setUrl(Ext.getStore('UserData').getAt(0).data.userid);
return true;
}
This way, it's ensured to set the url for your store's proxy right before it's loaded. And basically at the time, all core methods are instantiated.
Update: please try this with your Post store:
Ext.define('MyApp.store.Post',{
extend:'Ext.data.Store',
config: {
//autoLoad: true,
fields: ['title', 'link', 'author', 'contentSnippet', 'content'],
proxy: {
type: 'jsonp',
url: 'dummy url',
reader: {
type: 'json',
rootProperty: 'responseData.feed.entries'
}
},
},
initialize: function(){
console.log("loaded!");
this.getProxy().setUrl('https://ajax.googleapis.com/ajax/services/feed/load?v=1.0&q=http://feeds.feedburner.com/SenchaBlog');
//return true;
}
});
After reading the source code of the pull-to-refresh plugin, I see that Sencha Touch use an Ext.data.Operation instead of Ext.data.Store.load() function. So you will have to put it into the initialize method instead.
Use Ext.data.StoreManager.lookup('UserData') to get the store instance.
But in your case, I would use this somewhere, where you work with the userid:
var postsStoreInstance = ...;
postsStoreInstancegetProxy()._extraParams.userid = userid;
It adds a query paremetry to the store's proxy url
The way you do it is the correct way. What is the code of your store definition?
Make sure your store has storeId: 'UserData'.
See this working example:
Ext.define('User', {
extend: 'Ext.data.Model',
fields: [
{name: 'id'}
]
});
Ext.create( 'Ext.data.Store', {
model: 'User',
storeId: 'UserData'
});
Ext.define('MyApp.store.Post',{
extend:'Ext.data.Store',
config: {
model: 'MyApp.model.Post',
proxy: {
type: 'ajax',
url: 'http://mywebsite.com/get?userid=' + Ext.getStore('UserData'),
reader: {
type: 'json'
}
}
}
});

Resources