Specifying a root in the JSON for an EXTJS tree - json

I am creating a tree in ExtJS 3.4.0. I understand the JSON the component is expecting should be returned like this:
[{
id: 1,
text: 'Brian',
leaf: true,
checked: false
}]
but the JSON that i am getting retrurned to me has a root node like this:
{"message":
{"nodes":
[{
"text":"Brian",
"id":"1",
"leaf":true,
"checked":false
}]
}
}
I don't see a way to specify in my configuration where in the JSON, the actual tree data is. Is this even possible? I see a "root" paramater, but that is different. Is there a way to specify where in the incoming JSON to "start" from.
Oh and I don't have control over the incoming JSON or obviously I would just change the JSON. :-)
Thanks

I think you could do something like along these lines (from looking at the ext docs):
var treePanel = {
xtype: 'treepanel',
loader: new Ext.tree.TreeLoader(),
root: new Ext.tree.TreeNode({
expanded: true,
children: myJsonObject.message.nodes
})
}

The is a 'root' option in the reader for your Store's Proxy that you can use.
proxy: {
reader: {
type : 'json',
root : 'nodes'
},
// Other configs
}

Related

EmberJS 2.7 How to restructure/reformat/customize data returned from the store

I have what I think is a very simple issue, but I just don't get how to do this data manipulation. This sadly didn't help, even though it's the same pain I am feeling with Ember.
Here is a route:
route/dashboard.js:
import Ember from 'ember';
export default Ember.Route.extend({
// this is for testing, normally we get the data from the store
model: function() {
return this.get('modelTestData');
},
modelTestData: [{
name: 'gear',
colorByPoint: true,
data: [
{y: 10, name: 'Test1'},
{y: 12, name: 'Test2'},
{y: 40, name: 'Test3'}
]
}],
});
The structure of the 'modelTestData' object has to be exactly like that as it is passed into a child component that needs it structured that way.
I can easily get my data from the API and put it into the model:
model: function() {
return this.store.get('category');
},
But then I need to restructure it...but how?
I have to somehow iterate over the categories collection and extract parts of data from each record to replace the 'data' part of the modelTestData object.
So I have 3 issues I am completely stumped on:
How to 'get at' the attributes I need from the model?
How to structure them as an array of objects with 'y' and 'name'?
How to assign that structure to the 'data' property of modelTestData instead of it being hardcoded?
Categories is a JSONAPI object like this:
{
"data":[
{
"id":"1",
"type":"categories",
"attributes":{
"name":"Carrying system",
"total-grams":"0.0"
}
},
{
"id":"2",
"type":"categories",
"attributes":{
"name":"Shelter system",
"total-grams":"0.0"
}
}
]
}
I need to map the grams value to 'y' and the name to 'name' in modelTestData.
Note that the category data is used in other routes for other purposes exactly as returned by the API. So I don't want to change the model structure itself, or what the API returns...that will break other parts of the app that do use 'category' in its original structure.
This is a specific use case that this route needs to massage the data to pass to the child component as per the structure of modelTestData.
I also wonder whether this data manipulation task belongs in a route?
Should I somehow do this in the serliazer adapter, creating a new structure as say 'categoryWeights' so I can then do:
model: function() {
return this.store.get('categoryWeights');
},
EDIT
I have managed to do this in the route, but it just gives me an array of objects. I need a single object containing 2 properties and an embedded array of objects.
model() {
return this.store.findAll('category')
.then(categories => categories.map(category => {
let data = {
y: category.get('totalGrams'),
name: category.get('name')
};
return data;
}))
},
This should probably go into a computed property:
dataForSubModel: Ember.computed('model.#each.totalGrams', 'model.#each.name', {
get() {
return [{name: 'gear', colorByPoint: true, this.get('model').map(m => ({y:m.get('totalGrams'), name:m.get('name')}))}
}
}),
The serializer is the wrong place, because its not that you need to convert it between the server and your app, but between your app and a strange component.
Actually the best thing would be to refactor the component.
Ok I got this to work in the route.
model() {
return this.store.findAll('category')
.then( function(categories) {
let data = [];
data = categories.map(category => {
return {
y: category.get('totalGrams'),
name: category.get('name')
}
});
return [{name: 'gear', colorByPoint: true, data}];
})
},
I still have the feeling this should be done in the adapter or serializer. Would be happy to see answers that show how to do that.

Method for pre-processing JSON for EXTJS TreeGrid?

I'm trying to determine the best method for pre-processing JSON for usage in an EXTJS TreeGrid. It's my understanding that EXTJS is expecting JSON to be formatted in the following manner:
{
"text":".",
"children": [
{
Location:'New Jersey',
iconCls:'task-folder',
expanded: true,
children:[
{
Building:'North-west Building',
iconCls:'task-folder',
children: [
{
Computer: '#12345',
Owner: 'Tommy Maintz',
iconCls: 'task',
leaf: true
},
{
Computer: '#98776',
Owner: 'Robert Maintz',
iconCls: 'task',
leaf: true
}
]
}
]
}
]
}
Unfortunately, the data source I am working with outputs flat JSON as such:
{
Computer: '#12345',
Owner: 'Tommy Maintz',
Building:'North-west Building',
Location:'New Jersey'
}
{
Computer: '#98776',
Owner: 'Robert Maintz',
Building:'North-west Building',
Location:'New Jersey'
}
What EXT methods are at my disposal to pre-process my JSON to work with a TreeGrid?
There is no built-in function/method that would do what you want, hence a coding is inevitable. Some advices:
You wouldn't work with the string but you would use var o = Ext.decode(json); to convert the raw json to object o
You can use Ext.each() to iterate through the resulting array or object
I'd write a recursive routine that would construct the resulting nested object
When you have the object with the desired structure you can use tree.setRootNode(result) to populate the tree.

Ember Data 1.0 with none standard json

I'm looking to use json from Github's issues api with Ember Data.
The problem is that the return json is not formatted the way ember data wants it to be.
Github returns data as such.
[
{id: 0, title: 'test'},
{id: 1, title: "ect.."}
]
Where as Ember Data's RestAdapter expects it to be like:
{ issues: [
{id: 0, title: 'test'},
{id: 1, title: "ect.."}
] }
I assume based on some research that I need to override the Find and FindAll methods for the DS.RestAdapter
MyApp.Issue = DS.Model.extend({ ... });
MyApp.IssueAdapter = DS.RESTAdapter.extend({
host: 'https://api.github.com/repos/emberjs/ember.js',
find: function(store, type, id) {
...
},
findAll: function(store, type since) {
...
},
}
The problem is in the example if found there are a few out of data methods and it also does not explain how I can pass a array with out an key of "issues"
To be honest I'm really a complete noob to all this and most of this js is over my head but I feel like I'm close to figuring this out. Let me know if I'm on the right track.

ExtJS expand and select at startup

I need some solution in ExtJS.I have tree store:
Ext.onReady(function(){
var storeTree = Ext.create('Ext.data.TreeStore', {
autoLoad:false,
expanded: false,
proxy: {
type: 'ajax',
url: 'getOneLevelChilds',
},
root: {
text: 'Ext JS',
id: 'src',
expanded: true,
children:[]
},
...
]
});
and when my tree loads at the first time I load last selected child (for example yesterday I open tree and select one. I saved it's JSON on database. so now Expand my tree)
storeTree.load({
url: 'getLastSelectedChild'
});
OK, everything works! but now I need some solution.
when I load my tree at the startup (when it was loaded) I have JSON:
[
{"id":3, "text":"first",},
{"id":4, "text":"second",},
{
id:"0", text: "third", expanded: true, children:
[
{
id:"1", text: "child1", leaf: true
},
{
id:"2", text: "child2", leaf: true
}
]
},
]
but I also save selected node id in database. I know that id="2" was selected yeasterday. How can I select automatically that node at startup? (Only at startup, only when my tree will be loaded). how can I do that?
P.S when I use proxy in tree Store, selection is not workin like this:
var record = this.getStore().getNodeById('1');
this.getSelectionModel().select(record)
but it works when I dont use Proxy.
and also, I need that selection only at sturtup
Assuming by "only at startup" you mean with the store's first load event and you actually have a tree panel (otherwise you cannot select a node):
treeStore.on({
'load': function(store) {
var node = store.getNodeById(2); // your id here
treePanel.getSelectionModel().select([node]);
// alternatively, if also want to expand the path to the node
treePanel.selectPath(node.getPath());
},
single: true
});

EXTJS JsonStore not loading proeprly

I have a JSONStore like :
OrdersStore = Ext.extend(Ext.data.JsonStore, {
constructor: function(cfg) {
cfg = cfg || {};
OrdersStore.superclass.constructor.call(this, Ext.apply({
storeId: 'ordersStore',
url: '/ajaxSupport.action',
root: 'rows',
baseParams: {
action: 'getorderlegsearchgrid'
},
fields: [
{
name: 'orderId'
}
]
},
cfg));
}
});
new OrdersStore();
This store is attached to a grid : 'pendingOrdersGrid'.
When I do:
alert(Ext.util.JSON.encode(this.pendingOrdersGrid.getStore().getAt(0)));
I hope to get the first record. But I get 'null'
I can't give you a complete answer from this information but some hints:
don't extend a store with a fixed storeId, url or fields! That's really bad design
if possible use browser that supports a console (Firefox with firebug or IE with developer toolbar [or FF4/IE9]) and debug the content of your store in the console.
to read the content of a record try something like this.pendingOrdersGrid.getStore().getAt(0).data.orderId