Unable insert element in nested array dynamically - javascript

I am working on angular tree which is having a large nested array.
nodes :
public fonts: TreeModel = {
value: 'Fonts',
children: [
{
value: 'Serif - All my children and I are STATIC ¯\\_(ツ)_/¯',
settings: {
'static': true
},
children: [
{ value: 'Antiqua' },
{ value: 'DejaVu Serif' },
{ value: 'Garamond' },
{ value: 'Georgia' },
{ value: 'Times New Roman' },
{
value: 'Slab serif',
children: [
{ value: 'Candida' },
{ value: 'Swift' },
{ value: 'Guardian Egyptian' }
]
}
]
},
{
value: 'Sans-serif',
children: [
{ value: 'Arial' },
{ value: 'Century Gothic' },
{ value: 'DejaVu Sans' },
{ value: 'Futura' },
{ value: 'Geneva' },
{ value: 'Liberation Sans' }
]
}
]};
The Tree looks similar to one present in image :
Each time user clicks on Any node, an API request goes to bring Child of that node (JSON Array). then i need to append this response array into original tree array .
The problem I'm facing is how do i insert child of nodes dynamically into original array against the parent node user clicked on.
Any better solution of current problem will also be helpful for me.
Currently i am using angular2-tree-component to implement the tree.

Finally i got the solution.
I switched to ng2-tree to implement the tree.
It has all the in built methods for tree-nodes and also it is well documented.
npm: ng2-tree
For every node provide an id. When user clicks on any node call a method to add childs into it.
public addChildFFS(id: number | string, newNode: TreeModel) {
newNode.id = ++this.lastFFSNodeId;
const treeController = this.treeFFS.getControllerByNodeId(id);
if (treeController) {
treeController.addChild(newNode);
} else {}
}

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.

How to translate object data to a format known by react-d3-tree

I am currently having problems using my data in react-d3-tree. The data coming from the server is not compatible with the format that react-d3-tree accepts.
I was told that doing the process using a foreach function for every item will work, but I think that will be really slow, especially whe the data is too big.
The data (as shown in my console) right now is like this:
0: {
series: 'Fate'
type: 'Servant'
class: 'Saber',
},
1: {
series: 'Fate',
type: 'Servant'
class: 'Archer',
},
2: {
series: 'Fate',
type: 'Demi-servant'
class: 'Shielder',
}
And I want to achieve this structure:
[
{
name: 'Fate',
children: [
{
name: 'Servant',
children: [
{
name: 'Saber',
children: []
},
{
name: 'Archer',
children: []
}
]
},
{
name: 'Demi-servant',
children: [
{
name: 'Shielder',
children: []
}
]
}
]
}
]
This is only sample data, and later on, and I might be converting data with more children. Is there any npm package that can be helpful?
Nevermind, I actually found my answer.
I'll share these useful links in case anyone finds this question too.
https://www.npmjs.com/package/shape-json
https://www.npmjs.com/package/shape-array

how to get value of an attribute if we are not sure about the position of the attribute in an array in react native

Consider the array which I get as response from API call. what if the position of any one of the attributes gets changed and I want to get the attribute salary/id/idProperty i.e., If I am not sure about attribute position how can get its value without hard coding the array with index?
var arr = [
{
id: "alex",
idProperty: {
args: [
{
name: "alex_name"
},
{
salary: "16L"
}
]
}
},
{
id: "john",
idProperty: {
args: [
{
name: "john_name"
},
{
salary: "14L"
}
]
}
}
];

Recursively replacing values in an object

Say I have an object that looks like this:
{
_id: ObjectID(1234),
name: 'Corvid',
friends: [{
name: 'Magpie',
friends: [{
name: 'Raven'
}, {
name: 'Jackdaw',
friends: [{
name: Friends.ALL_FRIENDS
}]
}]
}, {
name: 'Jay'
}]
}
Essentially, what I am trying to do is, for every entry in list of friends, replace the current object with the result of Friends.findOne({ name: obj.name }).
I am easy able to iterate through the structure like so.
function populate(obj=friends) {
if (obj.friends) {
return populate(obj.friends);
}
return friends.findOne({ name: obj.name });
}
However, what I am having trouble with is replacing that object at that specific area. How would one go about doing this?

dijit.tree with empty folders

i have created a tree select that shows a dijit.tree in the dropdown. Now I do not want the user to select a folder even if it is empty. User should only be able to select the end nodes or leaves. dijit.tree treats all empty folders as leafs. how do I get that sorted?
You need to override the _onClick or setSelected methods. This gets complicated if you use the multi-parental model ForestStoreModel.
See fiddle.net
Try doing as such, this will only work for select multiple false:
getIconClass: function fileIconClass(item, nodeExpanded) {
var store = item._S,
get = function() {
return store.getValue(item, arguments[0]);
};
// scope: dijit.Tree
if (item.root || get("isDir")) {
if (!item || this.model.mayHaveChildren(item) || get("isDir")) {
return (nodeExpanded ? "dijitFolderOpened" : "dijitFolderClosed");
} else {
return "dijitLeaf";
}
} else {
return "dijitLeaf";
}
},
onClick: function(item, treeNode, e) {
var store = item._S,
get = function() {
return store.getValue(item, arguments[0]);
};
if (get("isDir")) this.set("selectedItems", []);
}
Adapt as you see fit, matching your json data - in particular the isDir, the above works on a sample of json like this
{
identifier: 'id',
label: 'foo',
items: [
{
id: 'item1',
foo: 'file1',
isDir: false},
{
id: 'item2',
foo: 'emptyDir',
isDir: true},
{
id: 'item3',
foo: 'dir',
isDir: true,
children: [
{
id: 'item3_1',
foo: 'fileInDir',
isDir: false}
]}
]
}

Categories