ExtJS 4 TreeStore Static JSON - won't load - javascript

I'm simply trying to get a static JSON file to load into a TreeStore, and I'm tearing my hair out.
I have a model:
Ext.define('pronghorn_ui_keyboard.model.CommandKey', {
extend: 'Ext.data.Model',
fields: [
{
name: 'id'
},
{
name: 'key'
},
{
name: 'command'
}
]
});
I have a TreeStore:
Ext.define('pronghorn_ui_keyboard.store.Commands', {
extend: 'Ext.data.TreeStore',
requires: [
'pronghorn_ui_keyboard.model.CommandKey'
],
constructor: function(cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.apply({
storeId: 'commands',
model: 'pronghorn_ui_keyboard.model.CommandKey',
proxy: {
type: 'ajax',
url: 'commands.json',
reader: {
type: 'json'
}
}
}, cfg)]);
}
});
And I have the following JSON at commands.json:
{
id: 'root',
key: null,
command: null,
children: [
{
id: 't'
key: 't'
command: null,
children: [
{
id: 'te'
key: 'e'
command: 'Trade Equity'
leaf: true
}
]
}
]
}
I'm trying to programmatically load this tree and inspect it in the console. In the Controller init function:
var me = this;
me.getCommandsStore().load({
callback: function() {
me.rootCommandKey = me.getCommandsStore().getRootNode();
me.currentCommandKey = me.rootCommandKey;
console.log(me.currentCommandKey);
console.log(me.currentCommandKey.id);
console.log(me.currentCommandKey.hasChildNodes());
me.initMainCommands();
},
scope: me
});
The console has something for currentCommandKey, but the ID isn't my root ID, and hasChildNodes() is false. So obviously the file isn't being loaded.
What am I doing wrong?

My JSON was invalid; basically missing commas.
Here's the correct JSON:
{
success: true,
children: [
{
string: 't',
key: 't',
command: null,
children: [
{
string: 'te',
key: 'e',
command: 'Trade Equity',
leaf: true
}
],
leaf: false
}
]
}
I need to do a better job of error handling with async calls too. I moved a bunch of stuff into methods on the Store itself and bound that init state on the load event using a local binding, which exposed a bunch of load-terminating-condition flags.

Related

Dynamically add values to specific property in object - Fluent UI React ContextualMenu

I have the following ContextualMenu structure inside my SPFx Extension build with Fluent UI React:
const menuProps: IContextualMenuProps = {
items: [
{
key: 'Access',
itemType: ContextualMenuItemType.Section,
sectionProps: {
topDivider: true,
bottomDivider: true,
title: 'Sites you have access to',
items: [
{ key: 'DynamicValue1.1', text: 'DynamicValue1.2' },
{ key: 'DynamicValue2.1', text: 'DynamicValue2.2' },
],
},
},
],
};
I also a MS Graph call running getting me some SharePoint Sites & Teams.
I would now like to push those dynamic responses to the to the menuProps at the right place.
So basically add the dynamic array into the nested items object.
items: [
{ key: 'DynamicValue1.1', text: 'DynamicValue1.2' },
{ key: 'DynamicValue2.1', text: 'DynamicValue2.2' },
],
How can I target that "object"? (hope I understand correctly and items is an object...)
Is there a way to do this using array.push()?
To make this library agnostic, it would look something like this:
const obj = {
items: [
{
key: 'Access',
itemType: '',
sectionProps: {
topDivider: true,
bottomDivider: true,
title: 'Sites you have access to',
items: [
{ key: 'DynamicValue1.1', text: 'DynamicValue1.2' },
{ key: 'DynamicValue2.1', text: 'DynamicValue2.2' },
],
},
},
],
};
obj.items[0].sectionProps.items.push({ key: 'DynamicValue3.1', text: 'DynamicValue3.2' })
console.log(obj.items[0].sectionProps.items)
Your console.log would return this:
[
{ key: 'DynamicValue1.1', text: 'DynamicValue1.2' },
{ key: 'DynamicValue2.1', text: 'DynamicValue2.2' },
{ key: 'DynamicValue3.1', text: 'DynamicValue3.2' }
]
If you can access menuProps: IContextualMenuProps, then just replace obj with the necessary variable.

sencha touch: cant remove record from session storage

Cant delete a record from the store.
My model
Ext.define('touch.model.FilesModel', {
extend: 'Ext.data.Model',
requires: [
'Ext.data.identifier.Uuid'
],
config: {
identifier: 'uuid',
idProperty: 'iD',
fields: [
{ name: 'iD', type: 'auto' },
{ name: 'fileName', type: 'auto' }
]
}
});
and this is my SessionStorage
Ext.define('touch.store.FilesStore', {
extend: 'Ext.data.Store',
requires: [
'Ext.data.proxy.SessionStorage'
],
config: {
storeId: 'FilesStore',
autoLoad: true,
model: 'touch.model.FilesModel',
proxy: {
type: 'sessionstorage',
id: 'FilesStore-store-unique'
},
sorters: [{
property: 'created',
direction: 'DESC'
}]
}
});
I am trying to remove a record from the store, and it doesnt work.
i tried:
var filesStore = Ext.getStore('FilesStore');
filesStore.remove(filesStore.getAt(index)); // fails on this line: "Uncaught TypeError: Cannot read property 'destroy' of null" remove from the store
filesStore.sync();
then i tried just to do
var filesStore = Ext.getStore('FilesStore');
filesStore.getAt(index).erase() // fails with: [ERROR][Anonymous] You are trying to erase a model instance that doesn't have a Proxy specified

ExtJS 4.2.1 - getters/setters using Associations not working

I'm having trouble trying to invoke getters/setters on a Model object that has an association with one other model. Here are the classes:
Category.js
Ext.define('Chapter05.model.Category', {
extend: 'Ext.data.Model',
fields: [
{ name: 'id', type: 'int' },
{ name: 'name', type: 'string' }
]
})
Product.js
Ext.define('Chapter05.model.Product', {
extend: 'Ext.data.Model',
requires: [
'Chapter05.model.Category'
],
fields: [
{ name: 'id', type: 'int' },
{ name: 'category_id', type: 'int' },
{ name: 'name', type: 'string' }
],
// we can use the belongsTo shortcut on the model to create a belongsTo association
associations: [
{ type: 'belongsTo', model: 'Chapter05.model.Category' }
]
})
Main.js
Ext.define('Chapter05.view.Main', {
extend: 'Ext.container.Container',
requires:[
'Ext.tab.Panel'
'Chapter05.model.Product',
'Chapter05.model.Category',
],
xtype: 'app-main',
layout: 'vbox',
items: [
{
xtype: 'button',
text: 'Category',
handler: function(evt) {
var product = new Chapter05.model.Product({
id: 100,
category_id: 20,
name: 'Sneakers'
});
product.getCategory(function(category, operation) {
// do something with the category object
alert(category.get('id')); // alerts 20
}, this);
}
}
]
});
The error occurs at the line where product.getCategory(...) is. I get the following message in Safari Web Inspector:
TypeError: 'undefined' is not a function (evaluating 'product.getCategory')
Am I forgetting to do something?
P.S.
The project(Chapter05) was generated using Sencha Cmd. Hence, the fully qualified names.
I've had a similar problem with a hasOne relation. It was solved by specifying the getters/setters and the associationKey yourself.
Something like:
belongsTo: {
model: 'Chapter05.model.Category',
getterName: 'getCategory',
setterName: 'setCategory',
associationKey: 'category_id'
}

ExtJS configure store to write list of models under a property name

I have a model like this:
Ext.define('Policy', {
extend: 'Ext.data.Model',
fields: [
{
name: 'id',
type: 'sting',
phantom: true,
convert: function(value, record) {
return record.get('a') + '#' +
record.get('b');
}
},
{name: 'a', type: 'string'},
{name: 'b', type: 'string'}]
});
Where the PK of each record is a and b. The store looks like this:
Ext.define('Store', {
extend: 'Ext.data.Store',
model: 'Policy',
autoLoad: true,
proxy: {
type: 'rest',
simpleSortMode: true,
batchActions: true,
reader: {
type: 'json',
root: 'data',
idProperty: 'id'
},
writer: {
nameProperty: 'mapping'
},
api: {
create:'/batch',
read: '/policies',
update: '/batch',
destroy: '/batch'
}
}
});
How can I configure the store so that when it POSTS to /batch when calling store.sync(), the payload looks like this and only consists of dirty records:
{
"policies": [{
"a": "AA",
"b": "BB",
}, {
"a": "AAA",
"b": "BBB"
},...]
}
where there is a policies property and under it is an array of dirty policies.
You can create whatever structure you want by making a manual Ext.Ajax() call. You have to submit only the dirty records yourself.

Load JSON in Ext store, associations missing

I'm using Ext 4.1. I have some issues with loading json data with associations. The flat data gets loaded perfectly, only the 'hasMany' doesn't work. (if loaded there nowhere to be found). If a record is loaded I want to be able to get the 2 stores of Attendee's and the 1 store of documents.
I can also change the JSON format to a better format (if you have suggestions let me know!)
I have this json data.
This is my first model:
Ext.define('App.model.package.LabVisit', {
extend: 'Ext.data.Model',
requires: [
'App.model.package.Attendee',
'App.model.package.Document'
],
idProperty: 'labVisitID',
fields: [
{
mapping: 'lab_visit_id',
name: 'labVisitID',
type: 'int'
},
{
mapping: 'lab_id',
name: 'labID',
type: 'int'
},
... some more irrelevant...
{
mapping: 'comments',
name: 'comments'
},
{
name: 'upddate'
}
],
hasMany: [
/* edit: added foreignKey (also tried with: lab_visit_id) */
{ model: 'package.Attendee', name: 'attendeeLabList', associationKey:'attendee_lab', foreignKey: 'labVisitId' },
{ model: 'package.Attendee', name: 'attendeeEmpList', associationKey:'attendee_emp', foreignKey: 'labVisitId' }
{ model: 'package.Document', name: 'document', associationKey:'document' },
]
});
I have following attendee model:
Ext.define('App.model.package.Attendee', {
extend: 'Ext.data.Model',
fields: [
/* edit: added this field */
{
mapping: 'lab_visit_id',
name: 'labVisitId'
},
{
mapping: 'attendee_id',
name: 'AttendeeID'
},
{
mapping: 'first_name',
name: 'firstName'
},
{
mapping: 'last_name',
name: 'lastName'
},
{
name: 'email'
}
]
});
following document model:
Ext.define('App.model.package.Document', {
extend: 'Ext.data.Model',
fields: [
{
mapping: 'document_id',
name: 'docID'
},
{
mapping: 'document_name',
name: 'docName'
},
{
mapping: 'document_mimetype',
name: 'mimeType'
},
{
name: 'uploadID'
}
]
});
Finally my store:
Ext.define('App.store.package.LabVisit', {
extend: 'Ext.data.JsonStore',
requires: [
'App.model.package.LabVisit'
],
constructor: function(cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.merge({
storeId: 'labVisitStore',
model: 'App.model.package.LabVisit',
remoteSort: true,
proxy: {
type: 'ajax',
api: {
read: API_URLS.getVisitList //url to the json
},
reader: {
type: 'json',
root: 'rows'
}
}
}, cfg)]);
}
});
Edit:
I've added the foreign key in the model and added it to the hasMany
Still no difference. This is my output:
I also find it a strange: If it's broken I expect an exception. And there are 2 mysterious stores always present but I don't have a clue why or what's the purpose.
The problem was in this part:
hasMany: [
{ model: 'package.Attendee', name: 'attendeeLabList', associationKey:'attendee_lab' },
{ model: 'package.Attendee', name: 'attendeeEmpList', associationKey:'attendee_emp' },
{ model: 'package.Document', name: 'document', associationKey:'document' },
]
#Izhaki helped me a lot. Thanx! Especially with the fiddle. I started there and begun with switching the code with my code piece by piece. Until I saw the model was the problem.
models should be defined like this: App.model.package.Attendee
I think it's sad that the framework doesn't show a significant error/warning if a model isn't recognised/doesn't excist/isn't supplied... But meh, it works now.

Categories