Angular sorting and ng-repeat

Question!

I'm working on reverse-engineering an Angular app that read data from a google sheet.

What I'm trying to do is create an array of "keys" using the unique values in the last column of the sheet that all contain rows of the source table. I then want to display on the page the key name, then beneath that all rows that have that same key.

Here's the code I have so far:

var app = angular.module('rowList', []);
app.controller('KeyCtrl', function($scope, $http, $sce) {
    angular.module('app', ['ngSanitize']);
    $scope.searchText = "";
    $scope.method = 'jsonp';
    $scope.url =
        "https://docs.google.com/spreadsheet/tq?tqx=responseHandler:JSON_CALLBACK&key=1SltKrRbL7CZEhOq42IHNvb-8_d-dJyL8e0zdKYUd0y4&single=true&gid=1&headers=2&tq=select A,B,C,D,E,F";
 
    $http({
        method: $scope.method,
        url: $scope.url
    }).success(function(data, status) {
        $scope.status = status;
    }).error(function(data, status) {
        $scope.data = data || "Request failed";
        $scope.status = status;
    });
    // create easy quick lookup for key
    var data = data.table;
    var keySort = {};
    for (var i = 0; i < data.rows.length; i++) {
        // sort rows in to the correct key
        // if the key doesn't exist, create an empty array
        if (!keysSort[data.rows[i].Keys]) {
            keysSort[data.rows[i].Keys] = [];
        }
        // add row
        keysSort[data.rows[i].Keys].push(data.rows[i]);
    }
    // get the keys
    var keyAry = Object.keys(keySort);
});
.appwrap {width:200px; background-color:cyan;}
.appwrap div {background-color:pink;}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="rowList">
<div ng-controller="KeyCtrl">
<div class="appwrap" ng-repeat='key in keyAry'>
    {{key}}
  <div ng-repeat='row in keySort.key'>
    {{row.ColA}}
  </div>
</div>

Before you respond I want to point out two things:

1) In the long run, I wont be using google sheets to run this app. I know it's not the most secure way to do things

2) As I said above, I'm trying to reverse engineer this from something that already exists. I'm sure there's wasted code in the JS (or something that doesn't make sense). I'm just trying my best.

If it helps, here's the link to the sheet the JSON data is coming from. (should be set for anyone to view).



Answers

Your perceived order of operations is incorrect. The code will execute like this:

// #1
$http({
    method: $scope.method,
    url: $scope.url
}).success(function(data, status) {
    // #3 if success
    $scope.status = status;
}).error(function(data, status) {
    // #3 if error
    $scope.data = data || "Request failed";
    $scope.status = status;
});

// #2
// create easy quick lookup for key
var data = data.table; //data is undefined !!!
var keySort = {};
for (var i = 0; i < data.rows.length; i++) {
    // sort rows in to the correct key
    // if the key doesn't exist, create an empty array
    if (!keysSort[data.rows[i].Keys]) {
        keysSort[data.rows[i].Keys] = [];
    }
    // add row
    keysSort[data.rows[i].Keys].push(data.rows[i]);
}
// get the keys
var keyAry = Object.keys(keySort);

Anything you want to happen after the data is returned from the $http call needes to go INSIDE the success method:

$http({
    method: $scope.method,
    url: $scope.url
}).success(function(data, status) {
    $scope.status = status;
    creatKeys(data);
}).error(function(data, status) {
    $scope.data = data || "Request failed";
    $scope.status = status;
});


function createKeys(data) {
  // create easy quick lookup for key
  var data = data.table;
  var keySort = {};
  for (var i = 0; i < data.rows.length; i++) {
      // sort rows in to the correct key
      // if the key doesn't exist, create an empty array
      if (!keysSort[data.rows[i].Keys]) {
          keysSort[data.rows[i].Keys] = [];
      }
      // add row
      keysSort[data.rows[i].Keys].push(data.rows[i]);
  }
  // get the keys
  var keyAry = Object.keys(keySort);
}

And, you need to set your key array on the $scope

$scope.keyAry = Object.keys(keySort);


Declare all your usable variables as a $scope attributes, to make it visible for the controller in ng-repeat='key in keyAry' and in row in keySort.key

    ...
    // get the keys
    $scope.keyAry  = Object.keys(keySort);
    $scope.keySort = keySort;
}
By : Igor


This video can help you solving your question :)
By: admin