How to add value to the children in nested array of objects - javascript

I have a nested array of objects i need to change the values of a children data dynamically
[
{
type: "root",
title: "FileManager",
isDirectory: true,
children: [
{
type: "folder",
title: "animals",
isDirectory: true,
children: [
{
type: "folder",
title: "cat",
isDirectory: true,
children: [
{
type: "folder",
title: "images",
isDirectory: true,
children: [
{
type: "file",
title: "cat001.jpg",
isDirectory: false,
}, {
type: "file",
title: "cat002.jpg",
isDirectory: false,
}
]
}
]
}
]
},
{
type : "folder",
title : 'Birds',
isDirectory : true,
children : []
}
]
}
]
this is my main array of object suppose if i want to change the value of children dynamically.
lets take i want to add one more object to the children inside images array
so the path of the images array is
FileManager / animals / cat / images
how can change the value of the children in the images object dynamically?

Based on the data structure provided, you can use a recursive solution to reach the nested array you are interested in and then when the recursion hits the base case, you can either push a new object/s into the array at that specific level of depth or use a callback function to push as many new objects into it.
I am not really sure about the "dynamic" part you are referring to, but the following should place you in the right direction:
function rec(array) {
for (let i in array) {
if (array[i].children === undefined) { // BASE CASE
// console.log("base case ", array);
// push the object you want into the array, as at this point in the
// recursion you will be at the level you can modify your image array as you like
return array.push({ "myImage": "myBeautifulCatImage", "does": "poooooor"});
}
// recursive call
// visualise how deep you are going...
// console.log("rec", array[i].children);
return rec(array[i].children);
}
}
rec(arr);
// if you know log your arr as in:
// console.log("arr after recursion", rec(arr))
// you will see your new cat showing where it should be :)
If this answer helps you solving the issue, consider accepting the answer or upvoting it. Thanks.

Related

Nested set tree view data structure using with recursing and traversal techniques in MongoDB or JavaScript

Hey I'm trying to implement nested drag&drop within re-order sequencesin my MERN app. I working to find ideal approach for mongodb data model and implement to Lexicographic order or linked lists for infinite sub folders. I used Model Tree Structures in this link but every node have limitless children for that require recursion and recursive functions or currying. Documentations not clear enough for make do that.
I want show all tree once and not sohuld appear after than click to arrow icon.There is my doodles for front side generation that working with only one depth such like graph nodes. Maybe Modified Preorder Tree Traversal implementation examples you have for this scenario.
const tree = data => { // immutable array
let ascendants = data.filter(d=>d.parent==null)
let descandants = data.filter(d=>d.parent)
**strong text**
let form = []
ascendants.map(a=>{
let node1 = {...a}; /// copying
let node1Children = [];
descandants.map(b=>{
let node2 = {...b};
if(node1._id == b.parent){
node1Children.push(node2)
}
})
node1.children = node1Children;
form.push(node1);
})
return form;
}
I cant take result with using $graphLookup because list format is not what i want.Could you give me some mongodb playground or grouping aggregate solutions? Below json examples shown my expecting results. I can do before but hardcode is unapropriate and performless. Is comparing good way?
[
// mongo database
{_id:123, title:'Books', slug:'books', parent:null },
{_id:124, title:'Programming', slug:'programming', parent:null },
{_id:125, title:'JavaScript', slug:'javascript', parent:'programming' },
{_id:126, title:'C++',slug:'cpp', parent:'programming' },
{_id:127, title:'React', slug:'react', parent:'javascript' },
{_id:128, title:'Redux', slug:'redux', parent:'react' },
{_id:129, title:'Toolkit', parent:'redux' },
{_id:130, title:'Saga', parent:'redux' },
{_id:131, title:'Nodejs', parent:'programming' },
{_id:132, title:'Databases', slug:'databases' },
{_id:133, title:'MongoDB', parent:'databases' },
]
[
// what i want
{ title: "Books"},
{ title: "Programming", parent:"computer-science", children: [
{ title: "JavaScript", children: [
{ title: "React", children: [
{ title: "Redux", children: [
{ title: "Saga" },
{ title: "Thunk" },
{ title: "Mobx" },
{ title: "Observable" },
{ title: "Context" },
{ title: "GraphQL" },
{ title: "Toolkit", children:[
{ title: "typescript" },
{ title: "slices", children:[
{ title: "createAsyncThunk" },
{ title: "createSlice" },
] },
] },
] },
{ title: "Nextjs" },
]},
{ title: "Vue", },
{ title: "angular", },
]},
{ title: "C++", },
{ title: "NodeJS", },
] },
{ title: "MongoDB", parent: "databases"},
]
You could create a Map to key your objects by slug. The values per key will be the result objects for parent objects. Include an entry for null, which will collect the top-level elements.
Then iterate the data again to populate children arrays -- when that property does not exist yet, create it on the fly. Finally output the top-level elements.
function makeTree(data) {
let children = []; // Top-level elements
let map = new Map(data.map(({title, slug}) => [slug, { title }]))
.set(null, {children});
for (let {slug, parent, title} of data) {
(map.get(parent || null).children ??= [])
.push(slug ? map.get(slug) : {title});
}
return children;
}
// Your mongodb data:
const data = [{_id:123, title:'Books', slug:'books', parent:null },{_id:124, title:'Programming', slug:'programming', parent:null },{_id:125, title:'JavaScript', slug:'javascript', parent:'programming' },{_id:126, title:'C++',slug:'cpp', parent:'programming' },{_id:127, title:'React', slug:'react', parent:'javascript' },{_id:128, title:'Redux', slug:'redux', parent:'react' },{_id:129, title:'Toolkit', parent:'redux' },{_id:130, title:'Saga', parent:'redux' },{_id:131, title:'Nodejs', parent:'programming' },{_id:132, title:'Databases', slug:'databases' },{_id:133, title:'MongoDB', parent:'databases' }];
console.log(makeTree(data));

Filtering on a Multi-Dimensional Array in Angular 2 App

I am trying to find a way to handle filtering an array with an array in my Angular 2 app. The data looks like this:
let services = [
{
flags: [
{
action: "Flag One",
completed: true,
},
{
action: "Flag Two",
completed: false,
},
],
ribbons: [
{
action: 'Ribbon One',
active: false,
},
{
action: 'Ribbon Two',
active: true,
},
]
}
]
Now, if I know what item within the second array to target, I can do this:
let filteredServices = services.filter(service => service.flags[0].completed === false);
console.dir(filteredServices);
However, generally I don't know which item within the inner array to target, so how can I write a filter function to iterate over both arrays and filter for the specific item I'm looking for? Would I use a combination of "filter" and "forEach"? Or is there a more succinct way to do this?
You can use filter with some
let filteredServices = services.filter((element) => element.flags.some((subElement) => subElement.completed === false));

Angularjs splice array of objects inside of an object always removes last object

I have an object which contains an array of objects called "blocks":
$scope.microsite = {
images: [
{url: "https://unsplash.it/800/400/?image=20"},
{url: "https://unsplash.it/800/400/?image=15"},
{url: "https://unsplash.it/800/400/?image=52"}
],
blocks: []
};
When I add stuff to this array, it behaves perfectly normally:
$scope.addElement = function(a){
if(a=='heroslider'){
var data = {
slides: [
{
id:0,
image:0,
title: "Title",
desc: "Description",
},
{
id:1,
image:1,
title: "Title",
desc: "Description",
},
{
id:2,
image:2,
title: "Title",
desc: "Description",
}
]
};
} else if(a=='threecol'){
var data = {
columns: [
{
title: "Column one",
text: "This is a column for features",
},
{
title: "Column two",
text: "This is a column for features",
}
]
};
}
var element = {
template: a,
data: data
};
$scope.microsite.blocks.push(element);
}
However when I try to remove an object from the array by calling this function on ng-click and passing in the object from an ng-repeat...
$scope.removeElement = function(element){
var x = $scope.microsite.blocks.indexOf(element);
console.log($scope.microsite.blocks[x]);
console.log(x);
$scope.microsite.blocks.splice(x, 1);
}
I am able to get both the correct object and the correct index in my console, but when it goes to splice the array, the last object is always being deleted which is very strange as this should only be happening when the index I'm trying to delete doesn't exist (and therefore would equal -1)
Any ideas why this could be happening?
EDIT: I have also tried using ng-click="microsite.blocks.splice($index, 1)" directly in the element, as well as passing the $index into the function instead of the element. In all cases, the correct index is found, but the result is still the same, only the last entry is ever deleted.
Turns out this was an error with "track by $index" in Angular. After removing "track by $index" from my ng-repeat, splice() functioned normally.

Delete item from nested object array

I'm working with AngularJS and have an object array like that in my controller :
$scope.folderList = [{
name: 'root',
path: 'uploads/',
subs: [{
name: 'pictures',
path: 'uploads/pictures',
subs: [{
...
}]
}, {
name: 'videos',
path: 'uploads/videos',
subs: [{
...
}]
}]
}];
For this nested array, I have 2 directives set them up in a nested UL LI list with ng-repeat.
Now I have my nested list of folders, and I want to trigger a function to delete the selected folder.
So I trigger my function to delete with "folder" in parameter, for example, if I trigger the "delete" function on the pictures folder, the folder parameter will be like that :
folder = {
name: 'pictures',
path: 'uploads/pictures',
subs: [{ ... }]
}
And I want to delete this object from the nested array.
With a 1 level object array, I use this :
var index = $scope.folderList.indexOf(folder);
delete $scope.folderList.splice(index, 1);
But it (obviously) doesn't work on a nested array !
How can I easily delete an entry from a nested array on JavaScript (or AngularJS ?)
I've heard that underscore.js was made for this, but I never used it, and after seeing their documentation I wasn't able to find the proper function to do this !
Thanks for your help !

How to fill an Ext.form.CheckboxGroup with checkboxes generated based on a JSON object returned from a server

I'm trying to dynamically fill an Ext.form.CheckboxGroup with Ext.form.Checkboxs derived from a JSON object pulled from a jsp page. My JSON object looks like this:
{
"sensors": [
{ "id": 200, "name": "name - B - A" },
{ "id": 201, "name": "name - B - B" },
{ "id": 202, "name": "name - C - A" },
{ "id": 203, "name": "name - C - B" }
]
}
I can load these objects into an Ext.data.JsonStore with code like this:
new Ext.data.JsonStore({
id: 'sensorStore',
autoLoad: true,
method: 'GET',
baseParams: {
jobType: 'sensor'
},
url: 'getstatus.jsp',
root: 'sensors',
sortInfo: { field: 'id', direction: 'ASC' },
fields: [ 'id', 'name' ]
}),
My understanding is that this will give me access to a set of Ext.data.Record objects, but I can't figure out how to go about iterating through those Records to create any Ext.form.Checkboxs, or if there's some other way of achieving the same result.
I'm not trying to set the values of the checkboxes, though I will need to be able to reference them when I submit the form.
Assuming the store is loaded (since you have autoLoad:true), you need to
iterate through the records to create an array of checkbox configs
create the checkboxgroup object (using the array created in #1 above as items config)
add this checkboxgroup to your form (or whatever container) and call this container's doLayout() if it is already rendered
Snippet to iterate and create checkbox configs-
var checkboxconfigs = []; //array of about to be checkboxes.
mystore.getRange().each(function(record){
checkboxconfigs.push({ //pushing into array
id:record.data.id,
boxLabel:record.data.name,
//any other checkbox properties, layout related or whatever
});
});
Snippet to create checkboxgroup-
var myCheckboxgroup = new Ext.form.CheckboxGroup({
id:'myGroup',
fieldLabel: 'Checkboxes in two columns',
columns:2,
items:checkboxconfigs //created in previous snippet.
//any other checkbox group configuration
});
Add to your container and redraw it-
mycontainer.add(myCheckboxgroup).doLayout();
EDIT - Your JsonStore config does not match to the data returned. (id needs to be an int)
new Ext.data.JsonStore({
id: 'sensorStore',
autoLoad: true,
method: 'GET',
baseParams: {
jobType: 'sensor'
},
url: 'getstatus.jsp',
root: 'sensors',
sortInfo: { field: 'id', direction: 'ASC' },
fields: [ {name:'id', type:int}, 'name' ]
}),

Categories