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

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.

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

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.