below is an example of the JSON I get from my REST endpoint. I need to create a tree-like structure from the subcategories arrays, which, as you can see, are recursively nested.
I searched and tried for almost a week now, but am unable to come up witha fully working solution -- the best I got so far was that the subcategories appeared both as children of their parent subcategory (as desired), but also as normal top-level nodes, which I clearly do not want.
my question is simply: how do I model this so that ember.js is able to create the desired tree-like structure?
I don't think this is very difficult for an experienced ember user, but as usual ember's documentation it is neither up-to-date nor does it cover more than trivial concepts.
wherever I look, the concept of such a nested structure seems to be alien (all nesting I find is with different types, but that is exactly what I don't need). the JSON format is immutable, I have to work with it the way it is.
I created my project with - ember-cli 0.2.7 - ember.js 1.13.0 - ember-data 1.13.4 using DS.RESTAdapter and DS.RESTSerializer
{
"id": 28,
"hassubcategories": true,
"CategoryName": "By Asset Type",
"subcategories": [
{
"id": 29,
"CategoryName": "Images",
"hassubcategories": true,
"subcategories": [
{
"id": 30,
"CategoryName": "Illustrations",
"hassubcategories": false
},
{
"id": 31,
"CategoryName": "Pictures",
"hassubcategories": true,
"subcategories": [
{
"id": 61,
"CategoryName": "BMP",
"hassubcategories": false
},
{
"id": 32,
"CategoryName": "EPS",
"hassubcategories": false
}
]
}
]
},
{
"id": 73,
"CategoryName": "InDesign (related)",
"hassubcategories": false
}
]
}
and this should render in a template to a tree-like list Images - Illustrations -- BMP -- EPS Indesign (related)
thanks for any help.
EDIT 2015-07-17: i am still not closer to a dynamic solution, but for the moment (thankfully, the levels are limited to two) i am happy with creating a subsubcategories model and sideload. i iterate over the payload, get the ids of each subcategory (2nd level) and move that subcategory to a list. my serializer subcategory:
import DS from 'ember-data';
import ember from 'ember';
export default DS.RESTSerializer.extend({
isNewSerializerAPI: true,
primaryKey: 'id',
normalizeHash: {
subcategories: function(hash) {
if(ember.get(hash, 'hassubcategories') && !ember.isEmpty(ember.get(hash, 'subcategories'))) {
var ids = [];
ember.get(hash, 'subcategories').forEach(function(cat){
ids.push(ember.get(cat, 'id'));
});
hash.children = ids;
}
return hash;
}
},
extractMeta: function(store, type, payload) {
if (payload && payload.subcategories) {
var subs = [];
var subs2 = [];
payload.subcategories.forEach(function(cat){
if(cat['hassubcategories']) {
var subsubs = cat['subcategories'];
subs.addObject(cat);
subs2.addObjects(subsubs);
} else {
subs.addObject(cat);
}
});
payload.subcategories = subs;
payload.subsubcategories = subs2;
}
delete payload.id; // keeps ember data from trying to parse "id" as a record (subcategory)
delete payload.hassubcategories; // keeps ember data from trying to parse "hassubcategories" as a record (subcategory)
delete payload.CategoryName; // keeps ember data from trying to parse "CategoryName" as a record (subcategory)
delete payload.ParentID; // keeps ember data from trying to parse "ParentID" as a record (subcategory)
}
});
and the models subcategory:
import DS from 'ember-data';
export default DS.Model.extend({
CategoryName: DS.attr('string'),
hassubcategories: DS.attr('boolean'),
children: DS.hasMany('subsubcategories', {async: false })
});
subsubcategory:
import DS from 'ember-data';
export default DS.Model.extend({
CategoryName: DS.attr('string'),
hassubcategories: DS.attr('boolean'),
});
maybe it helps somebody and maybe i even get a hint how to it truly dynamically.