Delete item from nested object array - javascript

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 !

Related

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

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.

How to pass one entry from a list as prop in Vue

Lets say I have the following list in data:
data: {
todos: [
{ id: 1, title: "Learn Python" },
{ id: 2, title: "Learn JS" },
{ id: 3, title: "Create WebApp" }
]
}
Now I want to pass only the entry with id of 2 to the prop:
<dynamic-prop :id=todos[2] :title="todos.title"> </dynamic-prop>
Is something like that possible in Vue?
Sure, you can pass any data on. Just don't forget to add quotation marks and mind the off-by-one problem. So if you want to pass the second element in a (zero-indexed) array, you'd write something like:
<dynamic-prop :id="todos[1].id" :title="todos[1].title"> </dynamic-prop>

VueFire watch for empty array property

looking around for a solution for my problem!
I try to make Vue.Draggable work with VueFire. I have a few lists with cards that can be dragged between them, sorted, cloned and so on. While the lists are populated with cards Vue.Draggable works perfectly, it watches for changes, triggers events like magic.
This is the working JSON:
categories: [{
name: "todo",
cards: ["second","first","second"]
},{
name: "doing"
cards: ["first","fourth","second"]
},{
name: "done",
cards: ["second", "fourth","first","third"]
}]
The problem comes when one o the lists is empty. We all know that Firebase doesn't store empty properties that's why Vue.Draggable can't watch for a property that doesn't exist. For example like this:
categories: [{
name: "todo",
cards: ["second","first","second"]
},{
name: "doing"
// missing cards property because it's empty
},{
name: "done",
cards: ["second", "fourth","first","third"]
}]
The cards property should be filled with values by dragging items to the list, but because cards doesn't exist Vue.Draggable can't watch for changes in that list and can't trigger events.
Is there a way to create some kind of placeholder or middleware to simulate that empty array? Or what are other possible solutions in this case?
Here's a small JSFiddle.
Thank you!
Why don't you initialize the cards property if nothing is returned from firebase?
categories: [{
name: "todo",
cards: ["second","first","second"]
},{
name: "doing",
cards: firebaseCollectionProperty || []
},{
name: "done",
cards: ["second", "fourth","first","third"]
}]

Push in array not reactive in HTML

When I remove a comment on my HTML var {{selecionados}} selected from, and I click on the list of names is all fine, but when HTML retreat or comment on again no longer works.
<script async src="//jsfiddle.net/raphaelscunha/9cwztvzv/1/embed/"></script>
Vue.js will only update your view when a property within the data object is changed, not when a new property is added. (See Change Detection Caveats in the Vue.js guide)
If you want it to react when ativo is set to true, make sure the property exists beforehand.
Try something like this when you're initializing your Vue object:
atores: [
{ name: 'Chuck Norris', ativo: false},
{ name: 'Bruce Lee', ativo: false },
{ name: 'Jackie Chan', ativo: false },
{ name: 'Jet Li', ativo: false}
]
JSFiddle

Traverse Nested JSON Objects - YUI AutoComplete

Say I have two different unrelated JSON Objects returned from separate AJAX requests
content: [{...}]
0: {...}
userId: "22"
name: "Kevin Johnson"
Manager: {…}
managerId: "123"
name: "Ryan Burke" //will be set as "searchValue"
content: [{...}]
0: {...}
companyId: "345"
companyName: "Trucks-R-Us" //will be set as "searchValue"
Building: {…}
buildingId: "5"
section: "North-West"
The attributes I've marked will be stored in a variable called searchValue (note they are not on the same level)
Can I access searchValue using YUI's AutoComplete plugin to locate the attributes I've specified using the combination of resultListLocator and resultTextLocator, regardless of what the key of the attribute is named or how nested the attribute is?
var autoComplete = new Y.AutoComplete({
inputNode: '#search-string',
resultListLocator: 'content',
resultTextLocator: function( return /** Find searchValue within nested Object**/),
resultHighlighter: 'phraseMatch',
maxResults: 10
});
Short version: Can my objects be traversed until a match to searchValue is found?
Can elaborate if this isn't enough detail

Categories