How to represent a tree of models with Ember Data? - javascript

I am looking for a way to generate a D3.js data structure from an Ember model, to convert my existing app to Ember. The goal is to display a tree of tasks, each task having 0 or more subtasks.
Here is the result I want to feed to D3.js :
[
{
"parent": 429,
"name": "Parent task 1",
"id": 428
"children": [
{
"parent": 428,
"name": "Sub task 1",
"id": 425
},
{
"parent": 428,
"name": "Sub task 2",
"id": 426
}
]
},
...
]
I tried to define my model like this :
Minp.Task = DS.Model.extend({
name: DS.attr(),
subtasks: DS.hasMany('task'),
data: Ember.computed(function () {
return {
id: this.get('id'),
name: this.get('name'),
type: 'task',
children: this.get('subtasks').map(function (task) {
return task.get('data');
})
};
}).property()
});
But I am getting a "Maximum call stack size exceeded" error. It seems that calling this from the data attributes causes it to be called again, in an infinite loop.
If i return an empty array for children, all works fine.
Do you have any idea why I am getting this ? Is it another way to do it ?

I think you're better off using associations, aren't you? Try using a self-referring data structure.
Minp.Task = DS.Model.extend({
parent: DS.belongsTo('task', inverse: 'children');
children: DS.hasMany('task', async: true, inverse: 'parent');
});
Hopefully that helps. Kind of depends what you want to do with these things, but that's what I generally use when I'm building tree-based data structures.

data is already a property on a DS.Model, and presumably it's getting invoked via the gets... which are now going into your redefinition of data, and causing your loop.

Related

Unable to output useState to imported chart

I have a simple form where i will add a task and add the amount of minutes that task has taken, i am having trouble trying to get the chart which i have imported from 'Recharts' to see the state, it looks like the state is returning an empty array and my chart is not seeing the data.
The Recharts chart takes an array with an object inside with two values, example shown below
const data = [
{ name: "Group A", data: 400 },
{ name: "Group B", data: 300 },
{ name: "Group C", data: 300 },
{ name: "Group D", data: 200 },
{ name: "Group E", data: 278 },
{ name: "Test Data", data: 189 }
];
However after i have moved my state as props to the component and mapped the result to take the same names as input the charts is not displaying anything
(my mapped props)
const activityData = [
...props.pieData.map(el => ({
name: el.title,
data: el.amount
}))
];
I have put a simplified version on codesandbox to make it a little bit easier if anyone wants to see the output i'm getting
https://codesandbox.io/s/hidden-dew-676xc
Found the issue as soon as i posted this, the 'data' value which i had mapped in my props was getting outputted as a string, when the object was expecting a number

AngularJS TreeView From JSON Object

I am newbie in AngularJS. I need to create a TreeView Structure From JSON Object.
My Return JSON Object is looks like below.
var categoryTree = [{Name:'Item1', Childnodes : {}, id: 1},
{Name:'Item2', Childnodes : {
items = [
{Name:'Sub Item21', Childnodes : {}, id: 21}
{Name:'Sub Item22', Childnodes : {}, id: 22}
]
}, id: 2}];
Could you please help me to create a AngularJS Tree View.
Thanks in Advance.
You can create a Tree view using the Webix framework along with AngularJS.
https://github.com/TheAjinkya/webixTreeWithJava-
https://github.com/TheAjinkya/AngularWebixApplication
treedata = [{
id: "1",
value: "Book 1",
data: [{
id: "1.1",
value: "Part 1"
},
{
id: "1.2",
value: "Part 2"
}
]
},
{
id: "2",
value: "Book 2",
data: [{
id: "2.1",
value: "Part 1"
}]
}
];
tree = new webix.ui({
view: "tree"
});
tree.parse(treedata)
<script src="https://cdn.webix.com/edge/webix.js"></script>
<link href="https://cdn.webix.com/edge/webix.css" rel="stylesheet" />
Please use some sort of tree view module. They can make your life much easier. The only thing is that you need to re-format your data structure to the tree module style. You can write a service and do all re-formatting inside a service.
Some tree view module and plugin:
http://ngmodules.org/modules/angular.treeview
https://angular-ui-tree.github.io/angular-ui-tree/#/basic-example

GetOrgChart: Nodes whose parent haven't been defined

I'm using the GetOrgChart JQuery plugin and running into a JavaScript error of:
Uncaught Type Error: Cannot read property '_ap' of null
I was able to determine that this is occurring in the case from my dataset where a user occurs earlier in the list than their manager does. My hierarchy is based around NTLogins, so the NTLogin of a given user is the id and the parentId is their manager's NTLogin.
$("#people").getOrgChart({
primaryColumns: ["Name"],
dataSource: [{
id: "bobeans125",
parentId: null,
Name: "Bob Beans"
}, {
id: "franklin884",
parentId: "tdawl756",
Name: "Frank Lin"
}, {
id: "tdawl756",
parentId: "bobeans125",
Name: "Tim Dawl"
}]
});
JSFIDDLE Demo
I have no good way that I can think of to order the data so that this doesn't occur other than finding all of the many root nodes and drilling down into the hierarchy manually so that the dataset being sent to GetOrgChart is ordered. However, the assumption of not having to do so was the primary driver for choosing GetOrgChart.
I ended up just recursively walking the tree and building the object in the right order. I was able to get it to load without error, however, the tree is too large to be displayed and requires being zoomed out too far to be useful.
Id : and ParentId: is integer value but you gave string value so your output is Error: Cannot read property '_ap' of null.
Correct Example:
$("#people").getOrgChart({
primaryColumns: ["Name"],
dataSource: [{
id: 1,
parentId: null,
Name: "Bob Beans"
}, {
id: 2,
parentId: 1,
Name: "Frank Lin"
}, {
id: "3",
parentId: "1",
Name: "Tim Dawl"
}]
});

How can I index child object properties in an array using ydn-db-fulltext?

I'm using Ydn-Db-Fulltext to allow users to search a local database of contacts in an HTML5 app. So far, when it comes to searching for names of people, it works great, is smart, and returns results instantly.
Here's an example of a contact object that contains an array of contact Methods:
{
"source": "COMPANY",
"ownerPin": "12345",
"name": "brian wilkins",
"dateUpdated": "2014-03-18T14:41:05.217Z",
"dateAdded": "2014-03-18T14:41:05.217Z",
"isFavorite": false,
"socialId": "54321",
"id": "1",
"deleted": false,
"edited": false,
"favorite": false,
"contactMethods": [
{
"id": "4321",
"contactKey": "12321",
"contactId": "1",
"value": "brian.wilkins#geemail.com",
"kind": "email",
"ownerPin": "12345",
"isPrimary": false
},
{
"id": "5432",
"contactKey": "2",
"contactId": "1",
"kind": "phone",
"ownerPin": "12345",
"isPrimary": false
},
{
"id": "23",
"contactKey": "333",
"contactId": "1",
"value": "112345",
"kind": "extension",
"ownerPin": "12345",
"isPrimary": false
}
]
}
To create the index on the "name" property, I setup the fullTextCatalog as follows:
fullTextCatalogs: [{
name: 'name',
lang: 'en',
sources: [
{
storeName: 'contacts',
keyPath: 'id',
weight: 1.0
}, {
storeName: 'contacts',
keyPath: 'name',
weight: 0.5
}
]
}],
stores: [
{
name: 'contacts',
keyPath: 'id',
autoIncrement: true
}
]
};
this.db = new ydn.db.Storage('thedatabase', db_schema);
I can search by name or by id (the key) and get a list of contacts that match. Little appears to be stored in memory. Every search queries the local backing indexedDB database.
The challenge is that I also want to be able to search based on email address and extension, which are stored in the contactMethods property inside an array of contactMethods. The "value" property is where we store the email address and/or extension depending on the contactMethod type.
I tried adding contactMethods as a secondary searchable object store, but this resulted in searches for "Brian" returning two results, both the contact containing the name, and the contactMethod containing the email address. Ideally, I'd want to take the contactId (foreign key to the contact) and use it to pull the actual contact object, but it seems like this could create very expensive overhead and negate the benefits of this great search tool.
Is there a way to index object properties that are not at the parent level? How can I approach this in a way that would scale and not eat up all of the resources?
this.db.get(entry.storeName, entry.primaryKey).done(function(x) {
this.textContent += ' [Full name: ' + x.name + ']'; // this is in the contact
this.textContent += ' [email: ' + x.value + ']'; // but this is in the contactMethod
}, span);
Is there a way to index object properties that are not at the parent level?
keyPath can refer to deep object property by using dotted notation. For example, you could specify contactMethods.value to index email, but unfortunately it does not work with array value - as in this case.
So, obvious choice is keeping contactMethods record in separate object store using parent-child relationship. Since ydn-db currently does not support embedded attribute in the schema, you will have to load all child records when loading parent object.
Alternatively, IndexedDB v2 may have virtual index generated by a function expression. You can use in ydn-db by generator in index schema, for example:
stores: [
{
name: 'contacts',
keyPath: 'id',
autoIncrement: true,
indexes: [{
name: '$emails',
multiEntry: true,
generator: function(record) {
return record.contactMethods.map(function(x) {return x.value};
})
}]
}
]
One thing to note though, the generated field $emails will appear when you load the data. It likely will be removed from the record so as to match with v2 spec.
We are using this generator index heavily in multiple projects, so I will fix bug.
Indexing id and email address in full text search is convenient, but does not make sense because phonetic base full text search will be index them as it is without normalization.

Correct render of js object with nodejs express

I have some structure that I want to render to my JADE page, so I decided to make JSON-like object to render some kind of data (variables, text, js objects), this JSON object looks like :
var dataSet1 = {
meta: {
"name": "Some text",
"minimum": mini_2,
"maximum": maxi_2,
"currentValue": last_data_2
},
data: {
"values": dataTwo,
"corridor": {
"x1": xc,
"x2": yc2,
"yw": yw2
}
}
};
My render line:
res.render('index', {
data_to_draw: JSON.stringify(dataSet1)
});
Then I`m using this rendered data on my JADE:
displayGraphExampleOne("#graph",
!{data_to_draw.data.values},
!{data_to_draw.meta.currentValue},
!{data_to_draw.meta.minimum},
!{data_to_draw.meta.maximum},
!{data_to_draw.meta.name},
!{data_to_draw.data.corridor.x1},
!{data_to_draw.data.corridor.x2},
!{data_to_draw.data.corridor.yw2});
Cannot read property 'values' of undefined
Im getting such type of error.
Im new with JS , so Im trying to decide what i`m doing wrong. If I will pass data not in js object - it works well, but i need such type of passing data.
thanx
Don't JSON.stringify the object, instead pass the object itself, otherwise you are trying to access the properties of a string, which obviously don't exist.
Just need to format code like this:
var dataSet1= [
{
"meta": {
"name": "Veocity variance",
"minimum": mini_1,
"maximum": maxi_1,
"currentValue": last_data_1
},
"data": {
"values": dataOne,
"corridor": {
"x1": xc,
"x2": yc1,
"yw": yw1
}
}
}
];
And use such call:
displayGraphExampleOne("#graph",
!{first_set}[0][0].data.values,
!{first_set}[0][0].meta.currentValue,
!{first_set}[0][0].meta.minimum,
!{first_set}[0][0].meta.maximum,
!{first_set}[0][0].meta.name,
!{first_set}[0][0].data.corridor.x1,
!{first_set}[0][0].data.corridor.x2,
!{first_set}[0][0].data.corridor.yw);
But not forget to render:
res.render('index', {
first_set: JSON.stringify([dataSet1, dataSet2, dataSet3]),
second_set: JSON.stringify([dataSet1, dataSet2, dataSet3]),
third_set: JSON.stringify([dataSet1, dataSet2, dataSet3])
});

Categories