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
Related
I'm working with ExtJs 6.2.0 and Java Spring MVC for the REST API.
I'm trying to delete an object from one of my store but I'm having a problem : instead of using my id named idCamp, extjs is using the field named id that contains an extjs generated id (for example: extModel47-1).
I'm working on the delete part but I didn't try to update a camp nor fetch one, but I think the configuration is the same for these three operations that need the id.
Here is my store:
Ext.define('XXXXXX.store.Camps', {
extend: 'Ext.data.Store',
alias: 'store.camps',
model: 'XXXXXX.model.Camp',
fields: [
'idCamp', // More irrelevant fields
],
autoLoad : true,
autoSync: true,
storeId: 'storeCamp',
proxy: {
type: 'rest',
idParam: 'idCamp',
url: // irrelevant,
reader: {
type: 'json',
rootProperty: 'data'
},
writer: {
type: 'json'
}
}
});
Here is my model:
Ext.define('XXXXXX.model.Camp', {
extend: 'Ext.data.Model',
idProperty: 'idCamp',
fields: [
{ name: 'idCamp', type: 'int' },
// More irrelevant fields
]
});
I also tried to put an idProperty inside the writer/reader inside the proxy but it didn't do anything.
Forgive my poor usage of the English language since I'm a French people.
Best regards,
Morony
The issue is using a combination of fields/model in your store definition. They are in competition with each other. Remove the fields definition.
I dynamically create my store from a model relation and attach this store to a grid.
var map = record.getCommunity().mappings();
map.load({
url: '/myUrl/mappings',
scope: this,
callback: function(records, operation, success) {
map.group('type');
//ExtJS bug https://www.sencha.com/forum/showthread.php?265674
me.getOutgoingGrid().destroy();
childGrid = Ext.create('hds.view.outgoingGrid', {
store: map
});
me.getGridHolder().add(childGrid);
me.getOutgoingGrid().getSelectionModel().select(0, false) ;
}
});
When I want to create a new model instance and insert it into this dynamic store I get the following error:
Cannot read property 'isModel' of undefined
Here is the code that triggers the error:
var newMap = Ext.create('hds.model.MappingModel', {
indetifier : "something",
});
me.getOutgoingGrid().store.insert(0, newMap);
I cannot found the reason of this problem....Any ideas?
It is hard to know what is breaking your code but here are a couple of things:
1 - You need to define the model identifier in the class prototype not in the instance.
2 - You misspelled identifier
So your model should look like:
Ext.define('hds.model.MappingModel', {
identifier : "something",
});
var newMap = new hds.model.MappingModel({
//...your config here
});
The error that you are seeing Cannot read property 'isModel' of undefined is thrown when the store tries to check if model is an instance of Ext.data.Model but the model being passed is undefined.
This can happen for several reasons but usually it's because you are trying to create a model before the prototype has been defined or because there is a typo on your code.
Please, try creating a a fiddle (https://fiddle.sencha.com) reproducing this error or it will be very hard to help you.
Regards,
If there was an fiddle, It would be more helpful. As I understand from your question, you have some data and you can't set the data to store or model correctly. If you had defined your model or store before set to grid, there would not be a problem. I added a fiddle how model proxy works with store and etc. Hope it helps. If the fiddle does not explain your problem, please change the fiddle codes. So, we can understand what your problem exactly. Here is the fiddle: https://fiddle.sencha.com/#fiddle/tvq
Ext.define('model.Users', {
extend: 'Ext.data.Model',
fields: [
{ name: 'Name', type: 'string'},
{ name: 'City', type: 'string'},
{ name: 'Country', type: 'string'},
],
//idProperty: 'Name',
proxy: {
type: 'ajax',
rootProperty: 'records',
rootUrl: 'users', // used when updating proxy url
url: 'users',
reader: {
type: 'json',
rootProperty: 'records'
}
}
}); //model
var modelExt = Ext.create('model.Users', { Name: 'Ernst Handel'});
var storeExt = Ext.create('Ext.data.Store', {
requires: 'model.Users',
model: 'model.Users'
});
modelExt.load({
scope: this,
success: function(record) {
var colObjects = [];
Ext.each(Object.keys(record.data), function(key) {
colObjects.push({
text: key,
dataIndex: key
});
});
storeExt.loadData([record]);
//console.log(record, storeExt);
var grid = Ext.create('Ext.grid.Panel', {
store: storeExt,
columns: colObjects,
renderTo: Ext.getBody()
});
},
failure: function (err) {
}
});
Create model like this and then use.
var newMap = Ext.create('Ext.data.model', {
identifier : "something"
});
Add a new file in Model folder named like MappingModel.js and define model like this.
Ext.define('hds.model.MappingModel', {
extend: 'Ext.data.Model',
fields: [
'something'
]
});
Add this in app.js and then use MappingModel in your dynamic store.
from my point of view I build the simplest way of model with associations in ExtJS.
Model:
Post --hasOne--> User
What I did:
Using a memory proxy
Follow the rule: Proxy in Model
Load a post object by Post.load(...).
But when I try to get the user object, it is not right loaded:
(Here the full source: http://jsfiddle.net/7XRw4/4/)
Ext.define('Post', {
extend: 'Ext.data.Model',
fields: ['user_id', 'content'],
hasOne: 'User',
proxy: {
type: 'memory',
data: {
posts: [
{id:1, user_id:1, content:'foo'},
{id:2, user_id:1, content:'bar'}
]
},
reader: {
type: 'json',
root: 'posts'
}
}
});
Ext.define('User', {
extend: 'Ext.data.Model',
fields: ['name'],
proxy: {
type: 'memory',
data: {
users: [
{id:1, name:'hans'},
{id:2, name:'klaus'}
]
},
reader: {
type: 'json',
root: 'users'
}
}
});
Ext.onReady(function() {
console.log("Ext.onReady() invoked...");
Post.load('1', {
success: function(record, operation) {
thePost = record;
console.log('thePost:', thePost);
theUser = thePost.getUser();
console.log('theUser:', theUser);
alert('The user name: ' + theUser.get('name'));
// The user object will not be right loaded! Why?
}
});
});
Isn't .getUser asynchronous? Meaning you should supply it with a success function and alert the user's name in that success function?
But I have had plenty of problems with hasOne relations in Ext. Documentation, tutorials, comments on documentation - they never agree and nothing works if you don't send the complete relation in the json.
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
UPDATE:
here is my reader/store - not sure what to add to the reader to make this work
Ext.define('YT.store.Videos', {
extend: 'Ext.data.Store',
model: 'YT.model.Video',
autoLoad: true,
proxy: {
type: 'ajax',
url: 'https://gdata.youtube.com/feeds/api/videos',
reader: {
type: 'json',
root: 'feed',
record: 'entry',
successProperty: 'success'
},
listeners: {
exception: function(store, response, app){
console.log('exception...');
console.log(response);
}
}
}
});
Here is my model:
Ext.define('YT.model.Video', {
extend: 'Ext.data.Model',
autoLoad: true,
fields: [
'title',
'published',
'content'
]
});
Here is a sample response:
{
version: '1.0',
encoding: 'UTF-8',
feed: {
junk: 'blahblahblahblah',
entry: [
title: {
$t: 'title'
},
content: {
encoding: 'flash/application',
src: 'http://youtube.com/watch?q=someCatVideo'
},
published: {
$t: '12-28-2012'
}
]
}
}
I'm not sure how to reconcile the two.
I've tried...
Ext.define('YT.model.Video', {
extend: 'Ext.data.Model',
autoLoad: true,
fields: [
{name: 'title', mapping: 'title.$t'},
{name: 'published', mapping: 'published.$t'},
{name: 'content', mapping: 'content.src'}
]
});
Bonus:
Definitely looking for tips on how to debug the implementation of these techniques, I'm rather new to JavaScript MVC.
You are on the right track with mapping, but you also need to define a reader where you specify where your records are in the JSON you get back - see official docs for good examples.
Incidentally, who thought $t was a good idea for a map key?
EDIT:
After your edits here is your working code:
http://jsfiddle.net/dbrin/mSJg3/
As far as debugging: the key for your issue was to clearly see the payload from the service (I used FireBug to inspect JSON object returned). Then mapping your Model class to fit the JSON object through mapping attribute and finally adjust JSON reader to let it know how to navigate your JSON payload (see my code example).
Once your exception listeners are not firing anymore (see code example for those again) that means you got your data into the store. To actually see the data I used Illuminations firebug plugin to inspect the data store. I saw only one record. What the heck? I observed id Property being set to some funky URL. This was happening by default as i did not specify an id attribute on the model. I resorted to spacifying idProperty to undefined to get around this funky behavior (see model code).
I used jsfiddle to quickly iterate through changes and running to see errors in the reader. Once I had no more errors I had jsfiddle show me the app I just build in such a way that I could use Illuminations plugin by using the show/light url: http://jsfiddle.net/dbrin/mSJg3/show/light/