Ng-repeat and control the display of information with ng-show or ng-if


#1

I do receive a JSON result and need to generate 6 variables after 3 loops controled by NumberTypes property, there are 3 diferent numbers, generating only one line of result.

How can i control in the templates using ng-show or ng-if the display of information and also how can angular interpret the variables as number and do the math?

My Controller receives the data and in the template i do ng-repeat and need to store data to
perform math calculations ( percentage and division)

The conditionals for the assignment of values and calculation would be :

if(item.NrType == 16 ){
	VlMonthAcfi2 = item.QttyRealPeriod; //QttyRealPeriod: "1069",
} else if(item.NrTipo == 17 ){
	VlYearAcfi2 = item.QttyRealPeriod;//QttyRealPeriod: "1069",
	VlPYearAcfi2 = item.QttyPlanPeriod; //QttyPlanPeriod: "1221",
} else if(item.NrTipo == 18 ){
	VlPlanedAcfi2 = item.QttyPlanPeriod; //QttyPlanPeriod: "29907",
}

The variables i need to generate:

lVlMonthAcfi2 = VlMonthAcfi2;       //16 - QttyRealPeriod
lVlPlanedAcfi2 = VlPlanedAcfi2); //18 - QttyPlanPeriod
lVlYearAcfi2 = VlYearAcfi2);       //17 - QttyRealPeriod
lVlPYearAcfi2 = VlPYearAcfi2);     //17 - QttyPlanPeriod
lVlPercAcfi2 =  VlYearAcfi2 * 100 / VlPYearAcfi2 + "%"; 
lVlPerc2Acfi2 =  VlYearAcfi2 * 100 / VlPlanedAcfi2 + "%";
//16 - QttyRealPeriod
//18 - QttyPlanPeriod
//17 - QttyRealPeriod
//17 - QttyPlanPeriod
//17 - QttyRealPeriod *100 / 17 - QttyPlanPeriod
//17 - QttyRealPeriod *100 / 18 - QttyPlanPeriod

This is the JSON data

{
	NrType: "16",
	DsType: "Inspection month",
	QttyPlanInitial: "0",
	QttyPlanPeriodic: "1221",
	QttyPlanAfterRepair: "0",
	ValuePlan: "0",
	QttyRealInitial: "0",
	QttyRealPeriodic: "1069",
	QttyRealAfterRepair: "0",
	ValueReal: "0"
},
{
	NrType: "17",
	DsType: "Inspection accumulated",
	QttyPlanInitial: "0",
	QttyPlanPeriodic: "1221",
	QttyPlanAfterRepair: "0",
	ValuePlan: "0",
	QttyRealInitial: "0",
	QttyRealPeriodic: "1069",
	QttyRealAfterRepair: "0",
	ValueReal: "0"
},
{
	NrType: "18",
	DsType: "Inspection year",
	QttyPlanInitial: "0",
	QttyPlanPeriodic: "29907",
	QttyPlanAfterRepair: "0",
	ValuePlan: "0",
	QttyRealInitial: "0",
	QttyRealPeriodic: "16504",
	QttyRealAfterRepair: "0",
	ValueReal: "0"
},

#2

Why not use angular.forEach in your controller? ng-repeat in the view is used for displaying data and not intended for looping through datasets and carrying out calculations.

Use the controller and angular.forEach to iterate through each of the datasets and carry out the calculations you need to make, then you can pass the result to $scope and display using ng-repeat as intended.


#3

This is my Controller:

.controller('AcpCtrl', function($scope, ApiAcp, $ionicLoading, $timeout ) {  
  $scope.data = null;
  $scope.previouscategory = '';
  
  $ionicLoading.show({
    noBackdrop: true,
    template: '<p class="item-icon-left">Please wait ...<ion-spinner class="spinner-calm"></ion-spinner></p>'
  });
  ApiAcp.getApiData()
    .then(function(result) {
      console.log(result);
      $scope.headers = ['Description','Real.', 'Real. year', 'Plan. year', 'Real. month', 'Plan. year', 'Real. year'];
      $scope.data = result;
    
      $ionicLoading.hide();
   })
})

Never try angular.foreach before, will try the docs example,

var log = [];
angular.forEach(result, function(value, key) {
  this.push(key + ': ' + value);
}, log);

#4

I try to use angular.foreach but the scope variables does not appear on the template is this sintax valid ?

angular.forEach(result, function(value, key) {
    //this.push(key + ': ' + value);
    
    if( result.NrType == 16 ){            
        $scope.VlMonthAcfi2 = result.QttyRealPeriod; //QttyRealPeriod: "1069",
    } else if( result.NrType == 17 ){
        $scope.VlYearAcfi2 = result.QttyRealPeriod;//QttyRealPeriod: "1069",
        $scope.VlPYearAcfi2 = result.QttyPlanPeriod; //QttyPlanPeriod: "1221",
    } else if( result.NrType == 18 ){
        $scope.VlPlanedAcfi2 = result.QttyPlanPeriod; //QttyPlanPeriod: "29907",
    }
    $scope.lblVlPercAcfi2  = parseInt($scope.VlYearAcfi2) * 100 / parseInt($scope.VlPYearAcfi2); 
    $scope.lblVlPerc2Acfi2 = parseInt($scope.VlYearAcfi2) * 100 / parseInt($scope.VlPlanedAcfi2); 

  });

In the template this is empty :

{{VlMonthAcfi2}}

#5

When you console.log the variable from the controller what value do you get?

Also your final $scope declarations are still inside the angular.forEach this will override the values. I don’t think you are understanding the purpose of $scope correctly, use local variables for your VlMonthAcfi2 etc then when you wish to display the result on a view assign to $scope


#6

I improve the php rest api doing all the math and deliver clean json, i just need to use ng-repeat in the template now.

I have a month select list and states select list how can i send these two post parameters ? can i use http post only ?

My conttroller:

.controller('AcpCtrl', function($scope, ApiAcp, $ionicLoading, $timeout ) {  
  $scope.data = null;
  $ionicLoading.show({
    noBackdrop: true,
    template: '<p class="item-icon-left">Searching ...<ion-spinner class="spinner-calm"></ion-spinner></p>'
  });
  ApiAcp.getApiData()
    .then(function(result) {      

  })
})

The factory :
.factory(‘ApiAcp’, function($http, $q, ApiAcpEndpoint) {
var getApiData = function() {
var q = $q.defer();
$http.get(ApiAcpEndpoint.url).success(function(data) {
q.resolve(data);
})
.error(function(error){
console.log(‘Had an error’+error)
q.reject(error);
})
return q.promise;
}
return {
getApiData: getApiData
};
})

In the template :

<tbody ng-repeat="item in data">

#7

It would depend on your API setup, you could use either POST or GET, but that’s not an Ionic related question.

As you are returning a promise from ApiAcp.getApiData why not setup a resolve on your route so that it’s already retrieved the api data before transitioning to that view?


#8

Thank you for the sugestion, i will research how to implement it as i am new to angularjs.


#9

You’ll find this really useful in your research https://github.com/angular-ui/ui-router/wiki#resolve Ionic uses angular ui-router.


#10

I search a formula to make two post data (month, origin ) reach the PHP API to return filtered JSON . I was already using states,and not sure about how to pass post parameters to my PHP API wich need to receive month and origin

eg.:
if( isset($_REQUEST['month']) ) {
	$month = $_REQUEST['month'];
} else {
	$month = date('m');
} 

I create a function inside the controller and it receives the post data (month and origin ) but the Json reponse is not modified, i do track and the post data (month, origin) and see this data do not reach the PHP API.

I try to use a resolve inside the state i need but not sure how to trigger this state only when i submit the search function : :confused:

 .state('app.acp', {
    url: '/acp',
    views: {
      'menuContent': {
        templateUrl: 'templates/acp.html',
        controller: 'AcpCtrl' 
      }
    }

/*
resolve:{

     // Example using function with simple return value.
     // Since it's not a promise, it resolves immediately.
     searchAcp:  function(){
        data: {
          month: data.month,
          origin: data.origin
        } 
        return {month: month};
     },
  }
*/

  })

#11

Your resolve has to ALWAYS return a promise. Otherwise it will never resolve.


#12

I try this way but still could not get a listing after a search

I do choose month and origin, submit it to an AngularJS controller, watching console.log inside then method the values are populated correctly.

The q.promisse wich is returned have this value: [object, object],

The list of the HTML template is not populated with the rigth expected values.

The values does not populate the PHP POST variable in the PHP API.

How can i populate the POST data ???

In my template i do submit to search method :

 <form method="post" ng-controller="AcpSearchCtrl" ng-submit="search(data)">
    <select name="month" ng-model="data.month">
      <option value="01">January</option>

And in my controller o do use http.post and a promisse:

.controller('AcpSearchCtrl', function($scope, ApiAcpSearch, $ionicLoading, $timeout, $http, ApiAcpEndpoint, $q) {  
  $scope.search = function(data) {
    $ionicLoading.show({
      noBackdrop: false,
      template: '<p>searching ...</p>'
    });
    var q = $q.defer();
    $scope.formData = {};
    $scope.submission = false;
    var param = function(data) {
          var returnString = '';
          for (d in data){
              if (data.hasOwnProperty(d))
                 returnString += d + '=' + data[d] + '&';
          }
          return returnString.slice( 0, returnString.length - 1 );
    };
    console.log('formData : '+$scope.formData);
    return $http({
      url:ApiAcpEndpoint.url,
      data : param($scope.formData),
      method : 'POST',
      headers : {'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8'}
    }) 
    .then(function(data) {      
          q.resolve(data);          
          var acp = {};
          acp.qdata = [ data ];
          $scope.data = acp.qdata;
          $ionicLoading.hide();
          return q.promise;
      });
  }
})

Output from console.log :

formData : [object Object]
controllers.js:323 http://localhost:8080/xmltojson/planed.php
controllers.js:331  2 AcpSearchCtrl data.month 05
controllers.js:332  2 AcpSearchCtrl data.origin 2
controllers.js:333  2 AcpSearchCtrl scope.month 05
controllers.js:334  2 AcpSearchCtrl scope.origin 2
controllers.js:341 AcpSearchCtrl  data :[object Object]