I have written a simple program to fetch data from an external JSON file and display it in Dojo Gridx. However, it is not working.
Dojo Code:
require(["dojo/text!json_to_gridx/js/data.json", "dojo/json", "gridx/Grid"], function(myJSONData, JSON, Gridx) {
// fetch and parse JSON
var myJSON = JSON.parse(myJSONData);
console.log(myJSON); // working fine
// create datastore
var store = myJSON; // should this be changed?
// create Gridx
if(!window.grid){
console.log('working'); // working fine
gridx = new Gridx({
id: 'grid',
store: store,
structure: [
{id: 'name', field: 'name', name: 'Name'},
{id: 'company', field: 'company', name: 'Company'}
]
});
console.log('working2'); // does not work
gridx.placeAt('gridContainer');
gridx.startup();
}
});
JSON:
[{"name": "Rahul Desai","company": "PSL"},{"name": "Alston","company": "PSL"}]
I am getting an error:
TypeError: cacheClass is not a constructor Model.js
How do I fix this? Please help!
EDIT: I was being suggested to use Memory Store and "gridx/core/model/cache/Async"
Now, the code for creating the Gridx looks like:
this._disksGrid = new Gridx({
id: 'grid',
cacheClass: asyncCache,
store: store,
structure: [
{id: 'name', field: 'name', name: 'Name'},
{id: 'company', field: 'company', name: 'Company'}
]
});
No error now, but the Gridx is not displayed. Any idea why?
EDIT 2: Turns out I was starting wrong grid in previous edit. Now the Gridx shows up but the second value is repeated and the first value does now show up.
Name Company
Alston PSL
Alston PSL
I made the changes mentioned in EDIT and EDIT 2 and also added unique IDs to every row of JSON and validated it correctly. That solved the problem.
Related
I created this fiddle showing what I want to do.
Basically, I configured a Store that loads only a single record (it reality it will be the currently signed in user). However, I can't seem to bind anything to that store properly. How can I get that {u.name} to output properly?
Here is the code:
Ext.define('User', {
extend: 'Ext.data.Model',
fields: ['id', 'name']
});
Ext.application({
name : 'Fiddle',
launch : function() {
new Ext.Component({
renderTo: Ext.getBody(),
viewModel: {
stores: {
u: {
proxy: {
type: 'ajax',
url: 'user.json'
},
model: 'User',
autoLoad: true
}
}
},
bind: 'Test name: {u.name}'
});
}
});
Try bind: 'Test name: {u.data.items.0.name}'
UPD:
As an explanation to this - u is an object with its properties, so trying to bind to u.name will actually bind to the name property of the store. Wile the store has no name property it will always be null. Store's received data is placed in data property. Items property contains a raw array of received data and so on.
In your fiddle you're using a store while it looks like you need just a single record.
Using links instead of stores should work better, like:
links: {
u: {
type: 'User',
id: 1
}
}
Working example based on your code: https://fiddle.sencha.com/#fiddle/uuh
I have a Model that contains an association to another Model. I am able to display the nested data into a form by using the mapping attribute on the field. Example:
Ext.define('Example.model.Request', {
extend: 'Ext.data.Model',
fields: [
{
name: 'id',
type: Ext.data.Types.NUMBER,
useNull: false
}
{
name: 'plan_surveyor',
mapping: 'plan.surveyor',
type: Ext.data.Types.STRING
}
],
associations: [
{type: 'hasOne', associationKey: 'plan', getterName:'getPlan', model: 'Specs.model.Plan'}
],
proxy: {
type: 'direct',
api: {
read: requestController.load,
update: requestController.update,
},
reader: {
type: 'json',
root: 'records'
},
writer: {
type: 'json',
writeAllFields: true,
nameProperty: 'mapping'
}
}
});
Using this method, I can display the plan.surveyor value in the form by reference plan_surveyor. I call Form.loadRecord(model) to pull the data from the model into the form.
However, now that I'm trying to send the data back to the server, I get the error:
Error performing action. Please report the following: "Unrecognized field "plan.surveyor"
I am attempting to save to the server by first calling Form.updateRecord(model), then model.save(). Is there a way to have the Writer understand that 'plan.surveyor' is not a property name but instead to properly handle nesting?
Am I doing this the right way to start with, or should I just be handling the setting of the form data and loading back into the model in a more manual fashion? It seems that nested data is not all that well supported in general - any recommendations?
Ext.define('Example.model.Request', {
extend: 'Ext.data.Model',
fields: [
{
name: 'id',
type: Ext.data.Types.NUMBER,
useNull: false
}
{
name: 'plan_surveyor',
mapping: 'plan.surveyor',//change to 'plan_surveyor'
type: Ext.data.Types.STRING
}
],
change that show in comment ,because data index is given in above format because ur give ur format thata time that is not dataindex it's a column or extjs preparatory ,so please change that may it's work well
it's not work u will send hole code
I'm new to sencha touch and I'm trying to parse an array of data (this doesn't seem like an uncommon use case but I can't find anything about it online). I followed the sencha ext.data.reader.json doc on nested json, but it doesn't work. Here are my models:
Search Results (to hold multiple search results):
Ext.define('GS.model.SearchResults', {
extend: 'Ext.data.Model',
autoLoad: true,
config: {
fields: [
{name: 'query', type: 'string'},
],
hasMany : {model: 'SearchResult', name: 'results'},
}
});
And search result, to hold an individual search result
Ext.define('GS.model.SearchResult', {
extend: 'Ext.data.Model',
config: {
fields: [
{name: 'id', type: 'int'},
{name: 'name', type: 'string'}
],
belongsTo: 'SearchResults'
}
});
Then in my controller, I have this code:
var store = Ext.create('Ext.data.Store', {
autoLoad: "true",
model: "GS.model.SearchResults",
proxy:
{
type: 'ajax',
url : 'www.someurl.com/?query=somequery',
reader: {
type: 'json'
}
}
});
store.load({
callback: function() {
console.log("Done Loading");
var root = store.first();
console.log("Results for " + root.get('query')); //this prints correctly
console.log(root.results());//THIS IS THE LINE IM INTERESTED IN
console.log(root.raw.results);//this weirdly works
//now I want to print each search results name
root.results().each(function(result) {
console.log("Song: " + result.get('name'));
});
}
});
}
When I log root.results(), I get
Uncaught TypeError: Object [object Object] has no method 'results'
This is exactly how they do it in the docs, so does anyone know why this isnt working???
Edit: Here is the doc I was following
The best way to check your error is to debug in chrome console. After callback you will find your records in root.raw or root.data.
I use to debug in chrome console and write the required code.
After some painful trial and error, I figured it out. In the tutorial, they used unconventional model name, but in my case I needed to use the fully qualified one
So to fix I needed to change
hasMany : {model: 'SearchResult', name: 'results'},
to
hasMany : {model: 'GS.model.SearchResult', name: 'results'},
and same with my deeper model like this:
belongsTo: 'GS.model.SearchResults'
Tough error to catch, but I hope this can help someone else in my position
I'm writing a simple application storing and displaying timestamped messages. Messages are JSON objects containing, say 2 main fields like:
{
"emitted": "2011-12-08 12:00:00",
"message": "This is message #666"
}
I have a model to describe these messages:
Ext.define('Message', {
extend: 'Ext.data.Model',
fields: [
{ name: 'emitted', type: 'date' },
{ name: 'message', type: 'string' }
]
});
I have no problem displaying these messages in a grid. However, i would now like to display these messages in a chart. For instance, I would be able to grab numbers (like the #666 in the above example) and display a line chart.
Ideally, i don't want to create a new store for the chart, i would like to reuse the same message store, but apply a filter on the fields to grab the proper value. I don't know, something that might look like:
var chart = {
xtype: 'chart',
...
series: [{
type: 'line',
axis: ['left', 'bottom'],
xField: 'emitted',
yField: {fieldName:'message', fieldGrabber: function(v) {
new RegExp("This is message #(\d+)$", "g").exec(v)[1]
}}
}]
};
Does this kind of thing is possible in ExtJS ?
I just tried to explain what I'm trying to do, i have no idea where to find such a feature: in the chart class, in the store class, or using a kind pf proxy to the store.
Side note:
I cannot ask the data to be properly formatted to the server. The messages I receive are not backed up anywhere, they are just live events streamed to the client via socketIO.
Any advices greatly appreciated!
You should extract the value inside you model to a separate field:
Ext.define('Message', {
extend: 'Ext.data.Model',
fields: [
{ name: 'emitted', type: 'date' },
{ name: 'message', type: 'string' },
{ name: 'nr', convert: function(v, r){
return r.get('message').replace(/^.*#/, '');
} }
]
});
Or you might be better off just having the 'nr' field and using a renderer in Grid that displays it as "This is message #{nr}".
Then you can use the 'nr' field directly in you chart.
I switched to Highcharts and threw ExtJS out to the trash :P
A particular request to my server returns x fields of JSON. I want to combine several of these fields and insert the concatenated data into the x+1 field of my JsonStore.
I know how to process the load event, read each record, concatenate the appropriate fields, and insert into my x+1st field. However, is there a better (more efficient) way to accomplish this - perhaps by overriding JsonReader?
You are looking for Ext.data.Field.convert
Reference - ExtJS 3.x / ExtJS 4.x
Example using 4.x version -
....
fields: [
'name', 'email',
{name: 'age', type: 'int'},
{name: 'gender', type: 'string', defaultValue: 'Unknown'},
{
name: 'whatever',
convert: function(value, record) {
return record.get('f1') + record.get('a2'),
}
}
]
....