0

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

Kunal Raut
2,6042 gold badges14 silver badges25 bronze badges
asked Jul 11, 2020 at 4:01
1
  • 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. Commented Jul 11, 2020 at 4:42

2 Answers 2

1

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.

answered Jul 11, 2020 at 12:49
Sign up to request clarification or add additional context in comments.

1 Comment

Awesome, many thanks. The array_map_with_keys function was smart.
1

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))

answered Jul 11, 2020 at 4:44

1 Comment

Great JS solution! Only selected the PHP solution because I would rather do it on the server side, but I will most certainly learn from this and use it in other scenarios

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.