{"0":
{
"text": "Entity_1",
"value": "",
"collapsed": true,
"children": {
"text": "Location_1",
"value": "",
"children": {
"text": "Service_1",
"value": "370"
}
}
}
}
{
"1": {
"text": "Entity_1",
"value": "",
"collapsed": true,
"children": {
"text": "Location_1",
"value": "",
"children": {
"text": "Service_2",
"value": "61"
}
}
}
}
{
"95": {
"text": "Entity_2",
"value": "",
"collapsed": true,
"children": {
"text": "Location_2",
"value": "",
"children": {
"text": "Service_45",
"value": "PP124"
}
}
}
}
{
text: "Entity_1",
value: "",
collapsed: true,
children: {
text: "Location_1",
value: "",
children: [
{ text: "Service_1", value: "370"},
{ text: "Service_2", value: "61"}
]
}
{
text: "Entity_2",
collapsed: true,
children: {
text: "Location_1",
value: "",
children: [
{ text: "Service_45", value: "PP124"},
]
}
$data = array();
$sql = "SELECT * FROM `services` ORDER BY `entity`, `location`";
$response = mysqli_query($conn, $sql);
if (mysqli_num_rows($response) > 0) {
while($result = mysqli_fetch_object($response)) {
$data = array(
...
)
}
}
There is a glaring error in this code. Let's look at what is happening<?php
define('DB_NAME','database_name');
define('DB_SERVER,'localhost');
define('DB_USER,'username');
define('DB_PASS,'password');
$dsn = 'mysql:dbname=' . DB_NAME . ';host=' . DB_SERVER;
$db = new PDO($dsn, DB_USER, DB_PASS);
[getServices.php]<?php
require_once('lib/database.php');
// Our default return
$data = [];
$sql = "SELECT * FROM `services` ORDER BY `entity`, `location`";
$stmt = $db->query($sql);
if ($stmt) {
// PDO Function that fetches all results in one call
$rows = $stmt->fetchAll();
// Convert to return structure
foreach($rows as $r) {
// Ensure we add to the array - not overwrite it
$data[] = getDataItem($r);
}
}
// Return the data using a utility function that
// sets the header and terminates the script.
sendJSON($data);
/*
* Utility to convert databaes row to TreeView object.
*/
function getDataItem($item) {
return [
'text' => $item->entity,
'value' => null,
'children' => [
'text' => $item->location,
'value' => null,
'children' => [
'text' => $item->service_description,
'value' => $item->service_code,
]
]
];
}
/*
* Utility to send JSON back to the client.
* Usually located in a helper script
*/
function sendJSON($resp, $terminate = true) {
header('Content-type: application/json');
echo json_encode($resp);
if ($terminate) die();
}
getServices(): Observable<Entity[]> {
const url = this.baseUrl + 'getServices.php';
return this.http.get<Entity[]>(url);
}
// Convert to return structure
foreach ($rows as $r) {
// Ensure we add to the array - not overwrite it
$data[] = getDataItem($r);
}
The values passed in the $r parameter reach the function, but then the returning property values are all null as seen here:function getDataItem($item)
{
return [
'text' => $item->entity, <-- line 43
'value' => null,
'children' => [
'text' => $item->location, <-- line 46
'value' => null,
'children' => [
'text' => $item->service_description, <-- line 49
'value' => $item->service_code, <-- line 50
]
]
];
}
What am I doing wrong?// Convert to return structure
foreach ($rows as $r) {
// Ensure we add to the array - not overwrite it
$data[] = getDataItem($r);
}
to read: // Convert to return structure
// Ensure we add to the array - not overwrite it
$data = getDataItem($rows);
and changed the getDataItem() to read: * Utility to convert databases row to TreeView object.
*/
function getDataItem($item)
{
$curEnt = $item[0]->entity; //Get current Entity value for later comparison
$curLoc = $item[0]->location; //Get current Location value for later comparison
foreach ($item as $index) {
(object)$services[] = [
'text' => $index->service_description,
'value' => $index->service_code
];
if ($index->location !== $curLoc) {
(object)$location[] = [
'text' => $curLoc,
'value' => null,
'collapsed' => true,
'children' => $services
];
$curLoc = $index->location;
(object)$services = [];
}
if ($index->entity !== $curEnt) {
(object)$entity[] = [
'text' => $curEnt,
'value' => null,
'collapsed' => true,
'children' => $location
];
$curEnt = $index->entity;
$services = (object)[];
$location = (object)[];
} elseif ($index->id === (string)count($item)) {
(object)$location[] = [
'text' => $curLoc,
'value' => null,
'collapsed' => true,
'children' => $services
];
(object)$entity[] = [
'text' => $curEnt,
'value' => null,
'collapsed' => true,
'children' => $location
];
}
}
return $entity;
}
thus producing this response: Copied Response #2.txt// What we want in the end
$tree = [];
// Keep track of nodes we have already seen
$index = [];
foreach($rows as $row) {
// Check if we have seen this top level item
$key_1 = $row->entity;
if (empty($index[$key_1])) {
// No? Create it and add it to the tree
$item = (object) [
'text' => $row->entity,
'value' => null,
'children' => []
];
$index[$key_1] = $item;
$tree[] = $item;
}
// Check if we have this second level item in the index
$key_2 = $key_1 . ':' . $row->location;
if (empty($index[$key_2])) {
// No? Create it, add it to the index and also add it
// to the current top level item
$item = (object) [
'text' => $row->location,
'value' => null,
'children' => []
];
$index[$key_2] = $item;
$index[$key_1]->children[] = $item;
}
// Same process for level 3 except now we set the value
$key_3 = $key_2 . ':' . $row->description;
if (empty($index[$key_3])) {
$item = (object) [
'text' => $row->description,
'value' => $row->service_code
];
$index[$key_3] = $item;
$index[$key_2]->children[] = $item;
}
}
// Now send the data back as JSON
sendJSON($tree);
[{"text":"EMGFA","value":null, ..., {"text":"Urg\u00eancia","value":"PP112"}]}]}]
this:{"text":"EMGFA","value":null, ..., {"text":"Urg\u00eancia","value":"PP112"}]}]}
Notice the absence of the starting and ending '[ ]'....
However, your JSON is not valid. You have multiple objects one after the other without a separator. Either these need to be sent individually
OR
You need to make them an array i.e. wrap in [ ] and put ',' between.
Having said that your data is confusing as you have objects with what appears to be array indexes INSIDE the object - so your first step is to figure out what you are meant to be sending back and get the data sorted out.
When you are done with that you can query the data like this
For example in your service
Open in new window
Open in new window