I am trying to create a javascript object as input for a bootstrap treeview. I have php that grabs data from mysql and json encodes the results into the following structure:
{"Company 1":{"Production":["Brands","Categories","Products","Stocks"],"Sales":["Customers","Orders","Staffs","Stores"]},"Company 2":{"Production":["Brands","Categories","Products","Stocks"],"Sales":["Customers","Orders","Staffs","Stores"]}}
PHP code to produce that json:
$databases=[];
foreach($result as $row){
$database=$row["database"];
$schema=$row["schema"];
$table=$row["object"];
if(!array_key_exists($database, $databases))
$databases[$database]=[];
if(!array_key_exists($schema, $databases[$database]))
$databases[$database][$schema]=[];
array_push($databases[$database][$schema], $table);
}
echo json_encode($databases);
But I am struggling to get that json structure into the nested array of JavaScript objects required. Below is the desired structure:
[ { text: "Company 1", nodes: [ { text: "Production", nodes: [ { text: "Brands" }, { text: "Categories" }, { text: "Products" }, { text: "Stocks" } ] }, { text: "Sales", nodes: [ { text: "Customers" }, { text: "Orders" }, { text: "Staffs" }, { text: "Stores" } ] } ] }, { text: "Company 2", nodes: [ { text: "Production", nodes: [ { text: "Brands" }, { text: "Categories" }, { text: "Products" }, { text: "Stocks" } ] }, { text: "Sales", nodes: [ { text: "Customers" }, { text: "Orders" }, { text: "Staffs" }, { text: "Stores" } ] } ] } ];
Any suggestions would be appreciated
-
If you can show the PHP array $result, then it will easy for us to figure out the structure of the array and how to manipulate it.Harish ST– Harish ST2020年07月11日 04:42:20 +00:00Commented Jul 11, 2020 at 4:42
2 Answers 2
I suggest a recursive flatItem function to do that.
I also introduce a array_map_with_keys helper function because PHP's own array_map function ignore keys and in your case, we need it.
function array_map_with_keys($callback, $array){
return array_map($callback, array_keys($array), $array);
}
function flatItem($key, $value) {
if(is_array($value)){
return
["text" => $key,
"nodes" => array_map_with_keys("flatItem", $value)
];
}else{
return ["text" => $value];
}
}
$converted = array_map_with_keys("flatItem", $databases);
echo json_encode($converted);
Result is what you expect :
[{"text":"Company 1","nodes":[{"text":"Production","nodes":[{"te
xt":"Brands"},{"text":"Categories"},{"text":"Products"},{"text":
"Stocks"}]},{"text":"Sales","nodes":[{"text":"Customers"},{"text
":"Orders"},{"text":"Staffs"},{"text":"Stores"}]}]},{"text":"Com
pany 2","nodes":[{"text":"Production","nodes":[{"text":"Brands"}
,{"text":"Categories"},{"text":"Products"},{"text":"Stocks"}]},{
"text":"Sales","nodes":[{"text":"Customers"},{"text":"Orders"},{
"text":"Staffs"},{"text":"Stores"}]}]}]
you can pass it on to the js.
1 Comment
const data = {
"Company 1": {
"Production": ["Brands", "Categories", "Products", "Stocks"],
"Sales": ["Customers", "Orders", "Staffs", "Stores"]
},
"Company 2": {
"Production": ["Brands", "Categories", "Products", "Stocks"],
"Sales": ["Customers", "Orders", "Staffs", "Stores"]
}
}
function converter(data) {
return Object.entries(data).reduce((converted, [key, val]) => {
const element = {
text: key,
nodes: [...Object.entries(val).map(([key2, val2]) => {
return {
text: key2,
nodes: [...Object.values(val2).map(val3 => {
return {
text: val3
}
})]
}
})]
}
converted.push(element);
return converted
}, []);
}
console.log(converter(data))