I have a PHP Server running and I'm using ionic/Angular.js for my mobile app. The app is sending requests to the server and the server responds with some json. Now I've got a strange bug.
This is my JS Code:
.controller('StatisticPlanDetailCtrl', function($scope, $stateParams, $http, SERVER) {
planID = $stateParams.planID;
time = $stateParams.time;
$http({
method: 'GET',
url: SERVER.url + 'listener.php?request=getHistoryEntry&planID=' + planID + '&time=' + time
}).then(function(data){
$scope.historyExercises = angular.copy(data.data);
});
})
The server will return the following:
[
{
"exerciseID":5,
"exerciseName":"Beinpresse",
"parameters":{
"Gewicht":{
"historyValue":"90 kg",
"planValue":"80 kg"
},
"Wiederholungen":{
"historyValue":null,
"planValue":"3 x 20 Whd"
}
}
},
{
"exerciseID":9,
"exerciseName":"Awesome Oberarm \u00dcbung",
"parameters":{
"Gewicht":{
"historyValue":null,
"planValue":"20 kg"
},
"Wiederholungen":{
"historyValue":null,
"planValue":"2 x 10 Whd"
},
"Hantel":{
"historyValue":null,
"planValue":"Gro\u00df"
},
"Stufe":{
"historyValue":null,
"planValue":"Hart"
}
}
}
]
Everything works so far. As you can see, it's not necessary that a historyValue is set. But the strange thing in this story is: When I set a breakpoint to the line where data.data is assigned to historyExercises, the data object only contains planValues and not a single historyValue, although one for "Gewicht" is set as you can see in the JSON output.
This is a screenshot of the Safari debug console:
It really does not make any sense why the planValue is passed an the historyValue is not
Edit listener.php
}else if($request == "getHistoryEntry"){
$planID = $_GET['planID'];
$time = $_GET['time'];
echo $services->getHistoryEntry($planID, $time);
}
And the part of service.php..:
public function getHistoryEntry($planID, $time){
$sql = "SELECT te.ExerciseID AS 'exerciseID',e.name AS 'exerciseName', p.Name AS 'parameter', te.value AS 'planValue', the.value AS 'historyValue'
FROM TrainingplanHistory th
INNER JOIN TrainingplanExercises te ON(te.TrainingPlanID = th.TrainingPlanID)
INNER JOIN Exercise e ON (e.ExerciseID = te.ExerciseID)
INNER JOIN Parameter p oN(p.ParameterID = te.ParameterID)
LEFT OUTER JOIN TrainingplanHistoryExercises the ON(the.TrainingplanID = th.TrainingPlanID AND the.Time = th.time AND
the.ExerciseID = te.ExerciseID AND the.ParameterID = te.ParameterID)
WHERE th.TrainingplanID = ? AND th.time = ?";
$bindings = array($planID, $time);
$exercises = $this->simplePDO->get_results($sql, $bindings);
$newExercises = array();
$lastExercise = array();
for ($i = 0; $i < count($exercises); $i++) {
$exercise = $exercises[$i];
if($lastExercise['exerciseID'] == $exercise->exerciseID){
$lastExercise['parameters'][$exercise->parameter]['historyValue'] = $exercises->historyValue;
$lastExercise['parameters'][$exercise->parameter]['planValue'] = $exercises->planValue;
if($i == (count($exercises)-1)){
//last element has to be added
array_push($newExercises, $lastExercise);
}
}else{
//new exercise
if($lastExercise != null)
array_push($newExercises, $lastExercise);
$lastExercise = array();
$lastExercise ['exerciseID'] = $exercise->exerciseID;
$lastExercise['exerciseName'] = $exercise->exerciseName;
$lastExercise['parameters'] = array();
$lastExercise['parameters'][$exercise->parameter]['historyValue'] = $exercises->historyValue;
$lastExercise['parameters'][$exercise->parameter]['planValue'] = $exercise->planValue;
if($i == (count($exercises)-1)){
//last element has to be added
array_push($newExercises, $lastExercise);
}
}
}
return json_encode($newExercises);
}
Exercises before loop: Array
(
[0] => stdClass Object
(
[exerciseID] => 5
[exerciseName] => Beinpresse
[parameter] => Gewicht
[planValue] => 80 kg
[historyValue] => 90 kg
)
[1] => stdClass Object
(
[exerciseID] => 5
[exerciseName] => Beinpresse
[parameter] => Wiederholungen
[planValue] => 3 x 20 Whd
[historyValue] =>
)
[2] => stdClass Object
(
[exerciseID] => 9
[exerciseName] => Awesome Oberarm Übung
[parameter] => Gewicht
[planValue] => 20 kg
[historyValue] =>
)
[3] => stdClass Object
(
[exerciseID] => 9
[exerciseName] => Awesome Oberarm Übung
[parameter] => Wiederholungen
[planValue] => 2 x 10 Whd
[historyValue] =>
)
[4] => stdClass Object
(
[exerciseID] => 9
[exerciseName] => Awesome Oberarm Übung
[parameter] => Hantel
[planValue] => Groß
[historyValue] =>
)
[5] => stdClass Object
(
[exerciseID] => 9
[exerciseName] => Awesome Oberarm Übung
[parameter] => Stufe
[planValue] => Hart
[historyValue] =>
)
)
Exercises after loop:
Array
(
[0] => Array
(
[exerciseID] => 5
[exerciseName] => Beinpresse
[parameters] => Array
(
[Gewicht] => Array
(
[planValue] => 80 kg
[historyValue] => 90 kg
)
[Wiederholungen] => Array
(
[planValue] => 3 x 20 Whd
[historyValue] =>
)
)
)
[1] => Array
(
[exerciseID] => 9
[exerciseName] => Awesome Oberarm Übung
[parameters] => Array
(
[Gewicht] => Array
(
[planValue] => 20 kg
[historyValue] =>
)
[Wiederholungen] => Array
(
[planValue] => 2 x 10 Whd
[historyValue] =>
)
[Hantel] => Array
(
[planValue] => Groß
[historyValue] =>
)
[Stufe] => Array
(
[planValue] => Hart
[historyValue] =>
)
)
)
)
This is the final output in the view:
And this is the code :
<ion-view view-title="Details">
<ion-content class="padding">
<ion-item class="item " ng-repeat="exercise in historyExercises" >
<div class="row">
<div>
<p><h2>{{exercise.exerciseName}}</h2></p>
<p ng-repeat="(parameter, value) in exercise.parameters">
{{parameter}}: {{value}}
</p>
</div>
</div>
</ion-item>
</ion-content>
</ion-view>