Now before you mark this question as duplicate, hear me out.
i have a json response in reactjs that goes like
organisationUnits: [
{
name: "0.Mzondo",
id: "nW4j6JDVFGn",
parent: {
id: "Ppx2evDIOFG"
}
},
{
name: "1 Chipho",
id: "eE4p4gXpR4p",
parent: {
id: "JKNTgsOVMOo"
}
}, {}, {}, ....
}]
now I have searched the net for a list-to-tree solution i've a lot of code from people but it doesn't seem to work.
Ive also tried https://github.com/yi-ge/js-tree-list and https://www.npmjs.com/package/list-to-tree and also https://www.npmjs.com/package/array-to-tree
but nothing works, i assume its because my parent id is trapped in the parenthesis. So nothing online works. If anyone has a solution to this, it'd be greatly appreciated.
Okay for all those that may get stuck in the future, here's how i solved the issue.
surprisingly I'm not very bright, so wrong career choice.... here goes
var arrayToTree = require('array-to-tree');
var array = [
{
name: "0.Mzondo",
id: "nW4j6JDVFGn",
parent: {
id: "Ppx2evDIOFG"
}
},
{
name: "1 Chipho",
id: "eE4p4gXpR4p",
parent: {
id: "JKNTgsOVMOo"
}
}, {}, {}, ....
}
array.map((item) => {
//
if(item.parent != null){
//console.log(item.parent.id)
item.parent = item.parent.id
} else {
item.parent = undefined
}
});
var tree = arrayToTree(array, {
parentProperty: 'parent',
customID: 'id'
});
console.log( tree );
this.setState({
orgUnits : tree
});
done.
Thank you so much to all those that helped. like really
Related
I am trying to make a tree table reorderable via drag and drop.
Here's the render for easier visualization:
I am also using React-DnD.
Here's a piece of my code:
const moveRow = useCallback(
(record: StructureElement) => (dragIndex, hoverIndex) => {
// console.log(record.name, dragIndex, hoverIndex);
const dragRow = sortableData[dragIndex];
if (!dragRow) {
console.log(sortableData, dragIndex);
} else {
console.log('drag', dragRow.name, 'hover', sortableData[hoverIndex].name);
}
// todo - change the order in array
},
[sortableData],
);
<StyledTreeTable
components={components}
dataSource={sortableData}
onRow={(record, index) => {
return {
index,
moveRow: moveRow(record as StructureElement),
};
}}
/>
So the problem is, my sortableData looks like this:
[
{ name: 1 },
{ name: 2 },
{
name: 3,
children: [
{ name: 11 },
{ name: 22 },
{ name: 33, children: [{ name: 111 }, { name: 222 }, { name: 333 }] },
],
},
];
So my objects can have more objects nested in children.
But moveRow function doesn't see it this way. For it, ABSTRACT_STATE_4 is of index 4. So when I try to reorder the array, I try to do this: data[4], which results in undefined.
Is there a way I can reorder the items in tree table with drag and drop, that I haven't found yet?
The only way I see of solving it now, is to recreate the array the way hover and drag indexes match. But that's a lot of seemingly unnecessary work.
Is there a way to get the record I am hovering over, like I'm getting hoverIndex?
I have an array with lots of games that have unique id. I need to make a request for every id to retrieve minutes played for that specific game.
So my array looks something like this:
[
{
id: 1,
name: 'Team 1 vs Team 2'
},
{
id: 2,
name: 'Team 1 vs Team 2'
},
{
id: 3,
name: 'Team 1 vs Team 2'
},
{
id: 4,
name: 'Team 1 vs Team 2'
},
{
id: 5,
name: 'Team 1 vs Team 2'
}
]
I have been trying to forEach through the array, make a request with Axios to the API and then retrieve the data.
The Api looks like this. It is alot more, just narrowed it down. there is an image below with more description:
{
event: {
123123: {
id: 1,
elapsed: {
1: {
elapsed: '45'
}
}
}
}
The elapsed key is unique, for some reason, so I am using a Object.keys to "find" it.
My code:
array.forEach(game => {
axios.get(`http://example.com/${game.id}`)
.then(res => {
let time = 0;
Object.keys(res.data.event).map(eventId) => { //the eventId is the id for the event, in this case 123123.
Object.keys(res.data.event[eventId].elapsed).map(el => {
time = res.data.event[eventId].elapsed[el].elapsed; //el is the key-id for the elapsed object.
)};
)};
return time;
});
});
This does not work, I just get undefined. What am I doing wrong? And yes, the API looks like a mess. I have images below in case that will help you. It's a JSON file, I just have a JSON Formatter:
EDIT: Edited my code
Is there a way that I can get another object inside of an object using a input parameter from a function. I have two different $scope variables I want to set for names, one for zone managers and another for construction managers. In this example I have looped inside of each object to grab the names. I would need to do this process twice, so I am not interested in repeating this numerous number of times so I create a function. The problem is that whenever I use "value.functionInputValue" I get an error saying that it cannot read from undefined. Can someone help me know where I have gone wrong?
JavaScript:
$scope.zones = [{
zoneManagers: {
zone1: {
name: 'Name',
phone: 1111111
},
zone2: {
name: 'Name',
phone: 1111111
},
zone3: {
name: 'Name',
phone: 1111111
},
constructionManagers: {
zone1: {
name: 'Name',
phone: 1111111
},
zone2: {
name: 'Name',
phone: 1111111
},
zone3: {
name: 'Name',
phone: 1111111
}
}
}];
function namesFilter(zoneType)
{
var allZoneManagerNames = [];
angular.forEach($scope.zones, function(value, key)
{
var zoneTypeArray = Object.keys(value);
if ( zoneTypeArray.indexOf(zoneType) != 1 )
{
angular.forEach(value.zoneType, function(value2, key2)
{
if (allZoneManagerNames.indexOf(value2.name) == -1)
{
allZoneManagerNames.push(value2.name);
}
});
}
});
return allZoneManagerNames;
}
$scope.allZoneManagerNames = namesFilter("zoneManagers");
I think it should be value[zoneType] instead of value.zoneType since zoneType is the String that you pass as a parameter to the function.
Also, as #mhodges mentioned, it should be zoneTypeArray.indexOf(zoneType) != -1 instead of zoneTypeArray.indexOf(zoneType) != 1 but, in this case, you can simply do the check like this:
if(value[zoneType]){
...
}
Try this fiddle
Your $scope.zones variable is a little complicated, so you have to do a nested lookup of object fields.
The fiddle is a little simplified version! and I removed the array because I thought it is not needed. As there is only a big object left (instead of an array), a check should be like this zones[zoneType], instead of indexOf.
There are several things wrong with this code, both syntactically and logically, so I will try to point them out for you to see if it fixes your issues.
1) $scope.zones.zoneManagers is missing an ending } before $scope.zones.constructionManagers
2) You should be checking if (value[zoneType]) not if (...indexOf(zoneType) != 1)
3) You should be iterating over value[zoneType] not value.zoneType
Updated Code Should Look Like This:
var app = angular.module('app', []);
app.controller('mainCtrl', function($scope) {
$scope.zones = [{
zoneManagers: {
zone1: {
name: 'zoneName1',
phone: 1111111
},
zone2: {
name: 'zoneName2',
phone: 1111111
},
zone3: {
name: 'zoneName3',
phone: 1111111
}
},
constructionManagers: {
zone1: {
name: 'constName1',
phone: 1111111
},
zone2: {
name: 'constName2',
phone: 1111111
},
zone3: {
name: 'constName3',
phone: 1111111
}
}
}];
function namesFilter(zoneType) {
var allZoneManagerNames = [];
angular.forEach($scope.zones, function(value, key) {
if (value[zoneType]) {
angular.forEach(value[zoneType], function(value2, key2) {
if (allZoneManagerNames.indexOf(value2.name) === -1) {
allZoneManagerNames.push(value2.name);
}
});
}
});
return allZoneManagerNames;
}
console.log('Zone managers => ', namesFilter('zoneManagers'));
console.log('Construction managers => ', namesFilter('constructionManagers'));
});
<!DOCTYPE html>
<html ng-app="app">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js"></script>
</head>
<body ng-controller="mainCtrl">
</body>
</html>
First of all i am very new to React JS. So that i am writing this question. I am trying this for three days.
What I have to do, make a list of category, like-
Category1
->Sub-Category1
->Sub-Category2
Categroy2
Category3
.
.
.
CategoryN
And I have this json data to make the listing
[
{
Id: 1,
Name: "Category1",
ParentId: 0,
},
{
Id: 5,
Name: "Sub-Category1",
ParentId: 1,
},
{
Id: 23,
Name: "Sub-Category2",
ParentId: 1,
},
{
Id: 50,
Name: "Category2",
ParentId: 0,
},
{
Id: 54,
Name: "Category3",
ParentId: 0,
},
];
I have tried many open source examples, but their json data format is not like mine. so that that are not useful for me. I have build something but that is not like my expected result. Here is my jsfiddle link what i have done.
https://jsfiddle.net/mrahman_cse/6wwan1fn/
Note: Every subcategory will goes under a category depend on "ParentId",If any one have "ParentId":0 then, it is actually a category, not subcategory. please see the JSON
Thanks in advance.
You can use this code jsfiddle
This example allows to add new nested categories, and do nested searching.
code with comments:
var SearchExample = React.createClass({
getInitialState: function() {
return {
searchString: ''
};
},
handleChange: function(e) {
this.setState({
searchString: e.target.value.trim().toLowerCase()
});
},
isMatch(e,searchString){
return e.Name.toLowerCase().match(searchString)
},
nestingSerch(e,searchString){
//recursive searching nesting
return this.isMatch(e,searchString) || (e.subcats.length && e.subcats.some(e=>this.nestingSerch(e,searchString)));
},
renderCat(cat){
//recursive rendering
return (
<li key={cat.Id}> {cat.Name}
{(cat.subcats && cat.subcats.length) ? <ul>{cat.subcats.map(this.renderCat)}</ul>:""}
</li>);
},
render() {
let {items} = this.props;
let {searchString} = this.state;
//filtering cattegories
if (searchString.length) {
items = items.filter(e=>this.nestingSerch(e,searchString))
console.log(items);
};
//nesting, adding to cattegories their subcatigories
items.forEach(e=>e.subcats=items.filter(el=>el.ParentId==e.Id));
//filter root categories
items=items.filter(e=>e.ParentId==0);
//filter root categories
return (
<div>
<input onChange={this.handleChange} placeholder="Type here" type="text" value={this.state.searchString}/>
<ul>{items.map(this.renderCat)}</ul>
</div>
);
}
});
I'm currently struggling with implementing a jQuery plugin to my site for tags (with custom data objects) with autocomplete. jQuery TextExt can be found here (http://textextjs.com/). I'm currently struggling with using custom data objects for each tag, which can only be chosen from what autocompletes. Based on this example (http://textextjs.com/manual/examples/tags-with-custom-data-objects.html) I'm trying to figure out how to return both "name" and "id" when a tag is chosen. Does anyone know how to achieve this or point me in the correct direction?
Perhaps the answer is somewhere in this example (http://textextjs.com/manual/examples/filter-with-suggestions.html)?
Here's what I have written, which isn't working (it only returns the name, I've tried adding 'item.id' to the functions but that didn't work for me either):
<script type="text/javascript">
jQuery(document).ready(function( $ ){
jQuery('#textarea').textext({
plugins: 'tags',
items: [
{ name: 'PHP', id: '1' },
{ name: 'Closure', id: '2' },
{ name: 'Java', id: '3' }
],
ext: {
itemManager: {
stringToItem: function(str)
{
return { name: str };
},
itemToString: function(item)
{
return item.name ;
},
compareItems: function(item1, item2)
{
return item1.name == item2.name;
}
}
}
});
})
</script>
Your itemManager code should probably look like this, you will need to store the suggestions in a custom array to look up their relevant ids in the stringToItem Method
itemManager: {
items: [], // A custom array that will be used to lookup id
stringToItem: function(str)
{
//Lookup id for the given str from our custom array
for (var i=0;i<this.items.length;i++)
if (this.items[i].name == str) {
id = this.items[i].id;
break;
}
return { name: str, id: id };
},
itemToString: function(item)
{
//Push items to our custom object
this.items.push(item);
return item.name ;
},
compareItems: function(item1, item2)
{
return item1.name == item2.name;
}
}