ExtJS 4.1 TreeStore doesn't load with association - extjs

I have a TreeStore, which works fine, but every node has some nested data, so I made a new model for it and used the hasMany association. But now the store loads nothing anymore. When I look into the records in the load event, they're empty, but the browser tells me the Ajax request delivered everything like before.
This is what the node data looks like, when it comes from the server:
{
"path": "KEY_518693",
"name": "KEY_518693",
"data": [
{
"branch": "KEY_518693",
"primnav": "ETC",
"X": 29261,
"Y": 96492
},
...
],
"children": [ ... ],
...
}
These are my model definitions:
TreeNode:
{
extend : 'Ext.data.Model',
requires: [
'DataRecord',
'Ext.data.association.HasMany'
],
fields : [
{ name: 'id' , type: 'string', mapping: 'path' },
{ name: 'text', type: 'string', mapping: 'name' },
...
],
hasMany : {
model: 'DataRecord',
name : 'data'
}
DataRecord:
{
extend: 'Ext.data.Model',
fields: [
{ name: 'branch' , type: 'string'},
{ name: 'primnav', type: 'string' },
{ name: 'X' , type: 'int' },
{ name: 'Y' , type: 'int' }
]
}
When I remove the association, the tree loads without problems. When I add data to the fields it gets parsed into the tree, but as "raw" object and not as model instance.

Please note that DataRecord has no field called treenode_id - so your hasMany association isn't complete. See docs for more info.

My approach had 2 problems.
The name of the association should not be 'data' or the records wont get loaded at all.
The primaryKey of the association has to be set right, in my case 'branch' was right

Related

How do I turn a sanity io document field that is an array of objects to an array of strings

I have a recipes.js document that has a tag field:
{
name: 'tags',
title: 'Tags',
type: 'array',
of: [{ type: 'reference', to: { type: 'tags' } }],
options: {
layout: 'tags',
},
},
it references another document called tags.js:
export default {
name: 'tags',
type: 'document',
title: 'Tags',
fields: [
{
name: 'title',
title: 'Title',
type: 'string',
},
],
};
I am trying to add the tags to each recipe as an array of strings in graphql. such as:
"tags": ['dinner', 'lunch', 'ribs']
but instead, I get an array of objects:
"tags": [
{
"title": "breakfast"
},
{
"title": "pancakes"
},
{
"title": "food"
}
]
How can I tell sanity all I want is each one to be added in as a string so it is an array of strings and not objects.
Sanity's GraphQL API does not support transforming the data structure into something else. If you want to do that, you will have to use GROQ.

Is it possible to have multiple hasMany relationships using the same model?

I have a situation where I have a model meant to store several lists of chemicals. The chemical model is the same for each of the hasMany relationships.
I need something like this:
Ext.define('HandSurvey.model.ChemicalRisks', {
extend: 'Ext.data.Model',
requires: ['Ext.data.identifier.Uuid'],
config: {
idProperty: 'id',
identifier: 'uuid',
fields: [
{ name: 'id', type: 'auto' }
],
associations: [
{
type: 'hasMany',
model : 'HandSurvey.model.SpecificChemical',
name : 'fiberglassResins',
store : {
type: 'sql'
}
},
{
type: 'hasMany',
model : 'HandSurvey.model.SpecificChemical',
name : 'paintsStains',
store : {
type: 'sql'
}
},
],
proxy: {
type: 'sql'
}
}
});
But this would cause each list to bind to every SpecificChemical that belongs to the ChemicalRisks model, not just the ones meant to belong to that hasMany. It seems as though I would need to join on multiple fields
Is it possible to do this? Or do I have to make a bunch of the exact same models/stores with different names?
sure you can!
use associationKey and the autogenerated stores of the associations
associations: [
{
type: 'hasMany',
model : 'HandSurvey.model.SpecificChemical',
name : 'fiberglassResins',
associationKey : 'fiberglassResins'
},
{
type: 'hasMany',
model : 'HandSurvey.model.SpecificChemical',
name : 'paintsStains',
associationKey : 'paintsStains'
},
]
Given a response like this: {
"response" : {
"fiberglassResins": [
{
"id" : 1
"name" : "Polyester"
},
{
"id" : 2
"name" : "E-Glass"
}
],
"paintsStains": [
{
"id" : 1
"name" : "item1"
},
{
"id" : 2
"name" : "item2"
}
]
}
}
Then you bind your main model to a store lets say ItemsStore.
IMPORTANT each record of ItemsStore will get autogenerated by Sencha: fiberglassResinsStore and paintsStainsStore.
Yo can console.log() each record to see the actual stores.

Creating a model for two jsonarray

demoAlerts({
itemstatus: [
{
item: "1",
name: "apple",
type: "fruit"
},
{
item: "2",
name: "pine",
type: "fruit"
}
],
deliverystatus: [
{
name: "james",
status: "yes"
},
{
name: "thomas",
status: "no"
},
]
});
I have two array (itemstatus and deliverystatus), I need to create the model for this store. what I tried is
ParentModel:
Ext.define('test.model.ParentModel', {
extend: 'Ext.data.Model',
requires:['test.model.ItemModel','test.model.DeliveryModel'],
autoLoad: true,
config : {
fields : [ 'itemstatus', {
name : 'demostatuslist',
model : 'demoAlerts.model.ItemModel',
mapping : 'itemstatus'
},
'portalstatus', {
name : 'deliverystatus',
model : 'test.model.DeliveryModel',
mapping : ' deliverystatus'
}]
}
});
ItemModel
Ext.define('demoAlerts.model.ItemModel', {
extend: 'Ext.data.Model',
config: {
fields: [
{ name: 'item', type: 'string' },
{ name: 'name', type: 'string' },
{ name: 'type', type: 'string' }
]
}
});
DeliveryModel
Ext.define('demoAlerts.model.DeliveryModel', {
extend: 'Ext.data.Model',
config: {
fields: [
{ name: 'name', type: 'string' },
{ name: 'status', type: 'string' },
]
}
});
Whether i properly configured the model. I am receiving the store as empty
Use Associations :) http://docs.sencha.com/touch/2.3.1/#!/api/Ext.data.association.Association
In this case I would have a Model with 2 hasMany associations like this:
Ext.define('demoAlerts.model.ContainerModel', {
extend : 'Ext.data.Model',
requires : [
'demoAlerts.model.DeliveryModel',
'demoAlerts.model.ItemModel'
],
config : {
associations: [
{
type : 'hasMany',
model : 'demoAlerts.model.DeliveryModel',
associationKey : 'deliveryStatus',
name : 'deliveryStatus',
autoLoad : true // this is very important
},
{
type : 'hasMany',
model : 'demoAlerts.model.ItemModel',
associationKey : 'itemStatus',
name : 'itemStatus',
autoLoad : true // this is very important
}
]
}
});
Then use a store SomeStore binded to ContainerModel.
IMPORTANT Each record in SomeStore will have deliveryStatusStore and itemStatusStore AUTOGENERATED.
Read about associations.
Neither http://docs.sencha.com/touch/2.3.1/#!/api/Ext.data.Field
nor http://docs.sencha.com/extjs/5.0/apidocs/#!/api/Ext.data.field.Field
knows a valid config option "model" for a field.
As far as I know, there is no such thing as a "Parent Model" available in ExtJS or Sencha Touch.
As far as I know, there is no possibility to have two stores in one.
You can load two (or more) stores using only one call to the server like in my following example:
firststore.on('load',function() {
secondstore.loadRawData(firststore.getProxy().getReader().rawData);
});
firststore.load()
Where you would give firststore the server url and the root of the data that goes into the first store, and secondstore will have the root of the data that goes into the second store.
Please be aware that the second store won't be filled if zero records go into the first store, and choose your stores appropriately.
If any of your stores can be the only empty store, perhaps you will have to get the rawdata via Ext.data.Request and load it into all stores afterwards.

Connect two models by ID

I asked an ExtJS question a few days ago, and as a side note I also asked how I could connect my two models. Main answer got answered, but I still couldn't figure out my other problem, so I am opening a new question for it.
It might be a silly problem again, but here it is:
I get a JSON from the server, that looks like this:
{
"success": true,
"result": {
"publishers": [
{
"id": "009999",
"type": "ABC",
"isReceipient": false,
"description": "XYZ"
},
{
"id": 45,
"type": "ABC",
"isReceipient": true,
"description": "XYZ"
},
{
"id": 45,
"type": "ABC",
"isReceipient": false,
"description": ""
}
],
"notes": [
{
"publisherId": "009999",
"text": "asdasd",
"created": "2014-02-23T18:24:06.074Z"
},
{
"publisherId": "46",
"text": "asdasd",
"created": "2014-02-23T18:24:06.074Z"
},
{
"publisherId": 45,
"text": "asdasd",
"created": "2014-02-23T18:24:06.074Z"
}
]
}
}
So I get two arrays, publishers and notes. I have two model for that, I load them in the models by the controller using loadRawData(), it works, I got all my publishers and notes in the store. (They both have a store - Publishers and Notes). But then I need to use the publisherId in notes to display publishers description. I tried a lot of things I could find using google and sancha docs: associations, hasmany, hasone, belongsto and creating a third store consisting of the two aggregated model. Nothing worked so far.
What I want is to have a store that has every notes, plus all notes have the publisher info.
I'll copy my two models below, you can see there, commented out what I have been trying. I also tried changing ID's, names etc., so variations of these. But I could never get the Notes to have the publisher's info.
Ext.define('MA.model.Note', {
extend: 'Ext.data.Model',
fields: [
'publisherId',
'text' ,
//hasone publisher
{
name: 'created',
type: 'date',
dateFormat: 'c'//'d-M-Y H:i:s' //"2014-02-23T18:24:06.074Z" needed: "02/23 18:24"
}
]
// hasOne: [
// {
// name: 'publisher',
// model: 'Publisher',
// associationKey: 'publisherId'
// }
// ],
// associations: [
// {
// type: 'hasOne',
// model: 'Publisher',
// primaryKey: 'id',
// foreignKey: 'publisherId'
// }
// ]
// associations : [
// {
// type : 'hasOne',
// model : 'MA.model.Publisher',
// getterName : 'getPublisher',
// associatedName : 'User',
// associationKey : 'User'
// },
// {
// type : 'belongsTo',
// model : 'MA.model.Publisher',
// getterName : 'getPublisher',
// associatedName : 'Publisher',
// associationKey : 'publisherId'
// }
// ]
// belongsTo: [
// {
// model: 'MA.model.Publisher',
// name: 'Note',
// primaryKey: 'publisherId',
// foreignKey: 'id',
// // foreignStore: 'Publishers'
// }
// ]
});
Publisher:
Ext.define('MA.model.Publisher', {
extend: 'Ext.data.Model',
idProperty: 'id',
fields: [
'id',
'type' ,
{
name:'isReceipient',
type:'boolean'
},
'description'
]
// hasMany: [
// {
// model: 'MA.model.Note',
// name: 'Note',
// primaryKey: 'id',
// foreignKey: 'publisherId',
// // foreignStore: 'Notes'
// }
// ],
});
Am I even on the right track? Should I use associations? I couldn't even really get the difference between associations and hasMan/One/belongTo properties, I guess there isn't any really, just the way you declare it.
Edit: My idea is to have a DataView class, that has a store which holds the notes and the corresponding publisher to the notes. I have a main panel:
items: [
{
xtype: 'create-note-panel',
flex: 1
},
{
xtype: 'notes-panel',
store: 'Notes',
flex: 1
}
]
And my notes-panel looks something like this:
Ext.define('MA.view.sections.notes.NotesPanel' ,{
extend: 'Ext.DataView',
alias: 'widget.notes-panel',
// deferInitialRefresh: true,
itemSelector: 'div.notes-list',
tpl: new Ext.XTemplate(
'<div class="notes-list">',
'<tpl for=".">',
'<p>{created}, by {publisherId}</p>',
'<p>{text}</p>',
'<hr />',
'</tpl>',
'</div>'
),
emptyText: 'No data available',
initComponent: function() {
var me = this,
publisherStore = Ext.data.StoreManager.lookup('Publishers');
//me.addEvents( //just messing here, trying stuff
// 'user-offer-activities'
//);
me.callParent(arguments);
}
//renderTo: Ext.getBody()
})
;
Notice the publisherId in the template. I need the publisher description there. I didn't want to use grid, as this DataView seemed a pretty good solution, I thought joining two stores would be easy, I just couldn't figure it out yet :(
I have created a fiddle that results in what you are after (displaying data from both models in the View).
It is a bit of a longwinded approach though, because of the way the tpl works you don't have access to the Model, just the data within it. So I created a function on the tpl that gets the record we're interested in from the model based on the publisherId.
https://fiddle.sencha.com/#fiddle/o9o
Note: I created the fiddle without using any associations between the models, but you could probably create a hasOne association from the Notes to Publisher with a foreignKey linking the id and publisherId in the respective models (though I still don't think this would enable you to refer to the members directly in the tpl).

Sencha touch 2.2 sql proxy not inserting data

I successfully tried sencha touch app example showed here
They are using store proxy type as localstorage, its working good and then i changed the proxy type to sql as shown below
Ext.define('notesApp.store.Notes', {
extend : 'Ext.data.Store',
requires : 'Ext.data.proxy.Sql',
config : {
model : 'notesApp.model.Note',
proxy : {
type : 'sql',
database: "SqlProxyTest",
table: "Notes",
id : 'notes-app-store'
},
sorters : [{property : 'dateCreated', direction : 'DESC'}],
grouper : {
sortProperty : 'dateCreated',
direction : 'DESC',
groupFn : function(record) {
if(record && record.data.dateCreated) {
return record.data.dateCreated.toString();
}
return '';
}
}
}
});
There is no error.
I can insert data and i can see the record in list view, but chrome resource showing "The Node table is empty".
If i refresh the browser the record is gone from the list.
Am i missing anything or is it right way to use sql proxy in sencha touch ?
If you have change your model (add a field) you have to drop the table and recreate it.
And when you add a new row on your datastore be sure to put all fields.
Example if i have a model with firstName, lastName, email :
// This one is not added cause email is absent
Ext.getStore('Users').add([{
firstName: 'Toto',
lastName: 'test',
}]);
// This one is added
Ext.getStore('Users').add([{
firstName: 'toto',
lastName: 'test',
email : 'toto#test.te'
}]);
The mistake i did was, i created id for the record i am trying to insert as they showed in that demo example, when i changed below model from
Ext.define("NotesApp.model.Note", {
extend: "Ext.data.Model",
config: {
idProperty: 'id',
fields: [
{ name: 'id', type: 'int' },
{ name: 'dateCreated', type: 'date', dateFormat: 'c' },
{ name: 'title', type: 'string' },
{ name: 'narrative', type: 'string' }
]
}
});
to
Ext.define('notesApp.model.Note', {
extend : 'Ext.data.Model',
config : {
fields : [
{ name : 'dateCreated', type : 'string', dateFormat : 'D'},
{ name : 'title', type : 'string'},
{ name : 'narrative', type : 'string'}
],
validations : [
{type : 'presence', field : 'dateCreated'},
{type : 'presence', field : 'title', message : 'Please enter a title for the note!'}
]
}
});
Everything works fine.

Resources