I have a nested JSON and I cannot seem to extract the nested array. I am not sure if I set up my store and models correctly. It seems right. As you can see at the bottom of this post, when I try to get the nested part out, it doesn't work.
JSON data:
{
"data":{
"name":"John",
"age":"23",
"gender":"Male",
"purchase":[
{
"item":"shirt",
"qty":1,
"price":10
},
{
"item":"hat",
"qty":2,
"price":25
},
{
"item":"pants",
"qty":1,
"price":15
}
]
},
"success":true,
"errorMsg":""
}
Store:
Ext.define('Pvm.store.MyStore', {
extend: 'Pvm.store.PvmBaseStore',
requires: [
'Pvm.model.Customer'
],
model: 'Pvm.model.Customer',
autoLoad: false
});
Customer Model:
Ext.define('Pvm.model.Customer', {
extend: 'Ext.data.Model',
requires: [
'Ext.data.Field',
'Ext.data.proxy.Ajax',
'Ext.data.reader.Json'
],
fields: [{
name: 'name',
type: 'auto'
}, {
name: 'age',
type: 'auto'
}, {
name: 'gender',
type: 'auto'
}],
associations: {
type: 'hasMany',
model: 'Pvm.model.Purchase',
name: 'purchase',
associationKey: 'purchase'
},
proxy: {
type: 'ajax',
actionMethods: {
create: 'POST',
read: 'POST', // changed read's method to POST (from GET) so we get the parameters as form data (not in URL, for security reasons)
update: 'POST',
destroy: 'POST'
},
url: '/pvmsvr/uiapi?cmd=readXml',
reader: {
type: 'json',
rootProperty: 'data'
}
}
});
Purchase Model:
Ext.define('Pvm.model.Purchase', {
extend: 'Ext.data.Model',
requires: [
'Ext.data.Field',
'Ext.data.proxy.Ajax',
'Ext.data.reader.Json'
],
fields: [{
name: 'item',
type: 'auto'
}, {
name: 'qty',
type: 'auto'
}, {
name: 'price',
type: 'auto'
}],
associations: {
type: 'belongsTo',
model: 'Pvm.model.Customer'
}
});
Controller Code:
onStoreLoaded: function(store, records, successful, eOpts) {
console.log(store); // works
console.log(records); // works
console.log(records[0].get('name')); // works
console.log(records[0].purchase(); // doesn't work; returns 'undefined'
}
I am idiot. I needed the child model's class name in the parent's requires...
Related
I have defined Ext.tree.Panel and on change of combo value, I am calling
tree.getStore().load();
Here is my treepanel code
Ext.define('InboxTreePanel', {
extend: 'Ext.tree.Panel',
xtype: 'inboxtreepanel',
height: 250,
initComponent: function() {
var me = this;
Ext.applyIf(me, {
store: Ext.create('Ext.data.TreeStore', {
fields: [{
name: 'id',
type: 'string'
}, {
name: 'text',
type: 'string'
}],
autoLoad: false,
proxy: {
type: 'jsonajax',
url: app_global.serviceExtn + 'browseS3.do',
reader: {
type: 'json',
root: 'results'
}
},
root: {
loaded: false
}
}),
columns: [{
xtype: 'treecolumn',
dataIndex: 'text',
flex: 1,
text: 'Nodes',
editor: 'textfield'
}]
});
me.callParent(arguments);
}
});
In return I am getting json data but data is not loading in treepanel
{"success":true,
"code":null,
"message":null,
"data":[{"id":"root/Date-2015-08-30","text":"Date-2015-08-30","leaf":false},
{"id":"root/Date-2015-08-31","text":"Date-2015-08-31","leaf":false},
{"id":"root/Date-2015-09-08","text":"Date-2015-09-08","leaf":false},
{"id":"root/Date-2015-09-09","text":"Date-2015-09-09","leaf":false}],
"totalCount":0}
Can anyone help why data is not loading in treepanel? What is wrong in my code
I have a simple model, let's say:
Ext.define('UserModel', {
extend: 'Ext.data.Model',
fields: [
{name: 'firstname', type: 'string'},
{name: 'lastname', type: 'string'}
]
});
And a json file that looks like this:
{
"DatabaseInJSON": {
"Users": [
{
"KeyFirstName": "John",
"KeyLastName": "Doe"
},{
"KeyFirstName": "James",
"KeyLastName": "Howlett"
}
],
"OtherStuffWeDontCareAbout": [
...
]
}
}
My question is:
If I create a store like this, how can i map the attribute "firstname" from my model to "KeyFirstName" from my json ?
Ext.define('my.custom.Store', {
extend: 'Ext.data.Store',
model: 'UserModel',
proxy: {
type: 'ajax',
url: 'path/to/my/file.json',
reader: {
type: 'json',
rootProperty: 'DatabaseInJSON'
}
}
});
You need to either employ mapping or a convert function
Have a look at the demo here which demonstrates both in action.
For the sake of the demo I turned your store into a memory proxy store and you are I presume also accessing your rootProperty wrong as it should be rootProperty: 'DatabaseInJSON.Users'
Code:
Ext.application({
name: 'Fiddle',
launch: function() {
myData = {
"DatabaseInJSON": {
"Users": [{
"KeyFirstName": "John",
"KeyLastName": "Doe"
}, {
"KeyFirstName": "James",
"KeyLastName": "Howlett"
}],
"OtherStuffWeDontCareAbout": {}
}
};
Ext.define('UserModel', {
extend: 'Ext.data.Model',
fields: [{
name: 'firstname',
mapping: 'KeyFirstName',
type: 'string'
}, {
name: 'lastname',
convert: function(v, record) {
return record.data.KeyLastName;
},
type: 'string'
}]
});
Ext.define('my.custom.Store', {
extend: 'Ext.data.Store',
model: 'UserModel',
proxy: {
type: 'memory',
reader: {
type: 'json',
rootProperty: 'DatabaseInJSON.Users'
}
}
});
myStore = Ext.create('my.custom.Store', {
data: myData
});
console.log(myStore.getRange());
}
});
Generally your Json properties should match the same names of your fields so that the reader can read them properly, to map 'KeyFirstName' to 'firstname' I think your best option would be to create a mapping in the field definition on the model.
This would apply this globally for all requests and I believe it would reverse the mapping when it come to saving the data.
To use the mapping in your case, you would need something like:
Ext.define('UserModel', {
extend: 'Ext.data.Model',
fields: [
{name: 'firstname', type: 'string', mapping: function(data) { return data.KeyFirstName; } },
{name: 'lastname', type: 'string', mapping: function(data) { return data.KeyLastName; } }
]
});
Other than changing the format of the JSON data, the only other way I can think of would be to override the read or getResponseData method of the JsonReader
I am a beginner in sencha programming trying to build an app that takes in data from a remote server and displays it as a list in my app. I am trying to load data from a JSON store into a listview. My Store Code is:
Ext.define('RestaurantGlobal.store.CategoryColumnsStore', {
extend: 'Ext.data.Store',
requires: [
'RestaurantGlobal.model.CategoryColumns'
],
config: {
model: 'RestaurantGlobal.model.CategoryColumns',
storeId: 'CategoryColumnsStore',
proxy: {
type: 'ajax',
url: 'http://eatpunjab.gramapp.in/Data/?Model=Category&All=True',
reader: {
type: 'json',
rootProperty: 'fields'
},
autoLoad: true
}
}
});
My Model Code is:
Ext.define('RestaurantGlobal.model.CategoryColumns', {
extend: 'Ext.data.Model',
uses: [
'RestaurantGlobal.model.BaseModelColumns'
],
config: {
fields: [
{
name: 'Name',
type: 'string'
},
{
name: 'Image',
type: 'string'
}
],
}
});
and my view code is:
var categorystore = Ext.create("RestaurantGlobal.store.CategoryColumnsStore");
Ext.define('RestaurantGlobal.view.CategoriesPage', {
extend: 'Ext.Panel',
config: {
styleHtmlCls: 'maincontainer',
styleHtmlContent: true,
layout: {
type: 'vbox'
},
items: [
{
xtype: 'titlebar',
flex: 0.5,
docked: 'top',
title: 'Menu'
},
{
xtype: 'list',
flex: 4,
cls:'customcontainer',
margin: '0 10 0 10',
itemTpl: [
'<img src="http://eatpunjab.gramapp.in/media/{Image}" width="40" height="40"/><h2>{Name}</h2>'
],
scrollToTopOnRefresh: false,
store: categorystore
},
]
}
});
When I open the app in my browser, I get a blank listview.
What is missing in my code that is causing the data to not be loaded into the listview?
autoLoad is a config option for the store, but you've put it in the proxy.
I am working in extjs4 mvc where I am getting stuck at a point. Actually I want to display associated json data in grid in extjs4. I tried and searched a lot but not yet get problem solved.
Here is my some code
my view file:
Ext.define('AM.view.user.List' ,{
extend: 'Ext.grid.Panel',
alias : 'widget.userlist',
title : 'All Users',
store: 'Users',
columns: [
{header: 'Name', dataIndex: 'name', flex: 1},
{header: 'Email', dataIndex: 'email', flex: 1},
{header:'title',dataIndex:'title',flex:1} //I tried
]
});
Controller file:
Ext.define('AM.controller.Users', {
extend: 'Ext.app.Controller',
stores: ['Users'],
models: ['User','Book'],
views: ['user.Edit', 'user.List'],
refs: [{
ref: 'usersPanel',
selector: 'panel'
}],
init: function() {
this.control({
'viewport > userlist dataview': {
itemdblclick: this.editUser
},
'useredit button[action=save]': {
click: this.updateUser
}
});
}
});
User model file:
Ext.define('AM.model.User', {
extend: 'Ext.data.Model',
fields: ['id', 'name', 'email'],
hasMany: {
model: 'AM.model.Book',
//model: 'Book',
foreignKey: 'userId',
name: 'books'
},
proxy: {
type: 'ajax',
api: {
read: 'data/users.json',
update: 'data/updateUsers.json'
},
reader: {
type: 'json',
root: 'users',
successProperty: 'success'
}
}
});
User store file :--
Ext.define('AM.store.Users', {
extend: 'Ext.data.Store',
model: 'AM.model.User',
autoLoad: true
});
Book model file:
Ext.define('AM.model.Book',{
extend: 'Ext.data.Model',
fields: [
{name: 'id', type: 'int'},
{name: 'title', type: 'string'}, //,mapping:'record[0].title' not working
{name: 'userId', type: 'int'}
]
});
json file:
{
"success": "true",
"users": [
{
"id": "1",
"name": "shilpa",
"email": "shilpa#sencha.com",
"books": [
{
"id": "10",
"title": "c++",
"userId": "1"
}
]
}
]
}
here is the screenshot:
please give me some suggestion to display associated data in grid.
You can access all the books in the column renderer and construct the string you need. It would be something like this:
{
text: 'Books',
renderer: function (val, meta, record) {
var books = '';
record.books().each(function(bookRecord, index, count) {
books = books + bookRecord.get('title') + ',';
});
return books;
}
}
http://jsfiddle.net/alexrom7/YQXC8/1/
i have json data like this
{"GetStudentDetails":
{"TotalCount":5,
"RootResults":[
{"city":"West Chester","country":"USA","state":"PA ","student_id":100},
{"city":"Philly","country":"USA","state":"PA","student_id":101},
{"city":"Buffalo","country":"USA","state":"NY","student_id":102},
{"city":"Naigra City","country":"USA","state":"NY","student_id":103},
{"city":"West Chester","country":"USA","state":"PA","student_id":104}]
}
}
How to get this data into a store?
i am trying using a model like this.
Ext.define('User', {
extend: 'Ext.data.Model',
fields: [
{ type: 'string', name: 'TotalCount' }
],
hasMany: [{ model: 'RootResults', name: 'RootResult'}]
});
Ext.define("RootResults", {
extend: 'Ext.data.Model',
fields: [
{ type: 'string', name: 'city' },
{ type: 'string', name: 'country' },
{ type: 'string', name: 'state' },
{ type: 'string', name: 'student_id' }
],
belongsTo: 'User'
});
var store = Ext.create('Ext.data.Store', {
model: 'User',
proxy: {
type: 'ajax',
url: 'users.json',
reader: {
type: 'json'
}
}
});
How should my model be? when i am giving some more simple json i am getting the store loaded. i think the problem is with mapping?
Define model as
Ext.define("RootResults", {
extend: 'Ext.data.Model',
fields: [
{ type: 'string', name: 'city' },
{ type: 'string', name: 'country' },
{ type: 'string', name: 'state' },
{ type: 'string', name: 'student_id' }
],
});
And inside the reader definition add two parameters:
root: 'GetStudentDetails.RootResults'
totalProperty: 'GetStudentDetails.TotalCount'
Something like that... Main idea - don't try to bring internal JSON structure to your model - it should be reader responsibility to properly parse it.