I am struggling with the finer points of using ngTable. I went through the ngTable ajax demo and tried to follow the example as reasonably as possible; however, I need to deviate from the part where the ngTable ajax demo defines an ngResource inline with the Controller.
I successfully built an ngTable with ngTable filters; My webapp is here (also see the plunker). This is an ngTable which:
The json REST service loads correctly, and the filters work. However, my problem is that the table is blank until I type something in the Filter field (see the before and after screenshots below).
The problem exists with all browsers I have tried:
I know the webapp is broken in Internet Exploder 9... I don't know why, but I really don't care about IE; this webapp is not going to be a public web service.
Note: The source code is at the bottom of the page... I built a plunker for it.
Note 1Sharp-eyed readers may notice that I'm using [[
and ]]
in my AngularJS form instead of the default curly-brace delimiters. I did this because I'm using Flask with Jinja (which also needs double curly-braces for its templating engine)..
BEFORE: Page is blank when I load it:
AFTER: However, if I type any character in the filters, the ngTable displays the data:
<script type="text/javascript">
"use strict";
// Set up an ngResource service to make HTTP GET / POST / DELETE calls
var Api = angular.module("api_main", ["ngResource"]);
Api.factory("restDemo", function ($resource) {
// http://www.masnun.com/2013/08/28/rest-access-in-angularjs-using-ngresource.html
return $resource("http://demo.pennington.net/demo/api/v1/data01", {}, {});
});
// Loosely based on this ngTable demo...
// http://bazalt-cms.com/ng-table/example/6
var App2 = angular.module('taskTable', ['ngRoute', 'api_main',
'ngTable']);
// Need to change AngularJS symbols when using flask + Jinja
App2.config(function($interpolateProvider) {
$interpolateProvider.startSymbol('[[');
$interpolateProvider.endSymbol(']]');
});
App2.controller('tableCntl', function($scope, $filter, restDemo, ngTableParams) {
var data = restDemo.query(); // HTTP GET for REST service
// Set up task table parameters
/* Lib3d's fix (i.e. data.$promise) is below */
data.$promise.then(function (data) {
/* the data is here, work with it */
$scope.tableParams = new ngTableParams({
page: 1, // show first page
count: 10, // count per page
total: data.length,
sorting: {
Column01: 'asc',
Column02: 'asc',
Column03: 'asc'
},
filter: {
Column01: "",
Column02: "",
Column03: "",
}
}, {
getData: function($defer, params) {
// Filtering
var orderedData = params.filter() ?
$filter('filter')(data, params.filter()) :
data;
// Sorting
orderedData = params.sorting() ?
$filter('orderBy')(orderedData, params.orderBy()) :
orderedData;
$defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));
/* set total for recalc pagination */
params.total(orderedData.length);
// This shouldn't be required, but keeping here in case
//if(!$scope.$$phase) {
// $scope.$apply();
//}
}
});
});
});
</script>
The broken demo source code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="description" content="">
<meta name="author" content="">
<link rel="stylesheet" href="http://yui.yahooapis.com/pure/0.4.2/pure-min.css">
<link rel="stylesheet" href="//cdn.jsdelivr.net/angular.ngtable/0.3.1/ng-table.css">
<!--
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/smoothness/jquery-ui.css">
<link rel="stylesheet" type="text/css" href="http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/css/jquery.dataTables.css">
-->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body {
padding-top: 30px; /* 30px pad at the top of screen */
}
</style>
<!-- Fix up title -->
<title>DATA DEMO</title>
</head>
<body>
<div class="pure-g">
</div>
<!-- Static navbar -->
<div class="pure-g">
<div id="menu" class="pure-u">
<div class="pure-menu pure-menu-horizontal pure-menu-open">
<ul>
<li><a href="#">Add Demo</a></li>
<li class="active"><a href="#">List Demo</a></li>
<li><a href="#">List Projects</a></li>
<li>
<a href="/login">Login</a>
</ul>
</div><!--/.nav-collapse -->
</div>
</div>
<!--- insert stuff here -->
<div id="Tasks" ng-app="taskTable" ng-controller="tableCntl">
<p><strong>Filter:</strong> [[tableParams.filter()|json]]
<table ng-table="tableParams" show-filter="true" class="table">
<tbody>
<tr ng-repeat="words in $data">
<td data-title="'Column01'" sortable="Column01" filter="{'Column01': 'text'}">
[[words.Column01]]
</td>
<td data-title="'Column02'" sortable="Column02" filter="{'Column02': 'text'}">
[[words.Column02]]
</td>
<td data-title="'Column03'" sortable="Column03" filter="{'Column03': 'text'}">
[[words.Column03]]
</td>
</tr>
</tbody>
</table>
</div>
</body>
<!-- insert JS at the bottom of the page -->
<footer>
<!-- all flash messages are processed here -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.min.js"></script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular-route.min.js"></script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular-resource.min.js"></script>
<script type="text/javascript" src="//cdn.jsdelivr.net/angular.ngtable/0.3.1/ng-table.js"></script>
<!--
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.5.1/moment.min.js"></script>
-->
<script type="text/javascript">
"use strict";
// Set up an ngResource service to make HTTP GET / POST / DELETE calls
var Api = angular.module("api_main", ["ngResource"]);
Api.factory("restDemo", function ($resource) {
// http://www.masnun.com/2013/08/28/rest-access-in-angularjs-using-ngresource.html
return $resource("http://demo.pennington.net/demo/api/v1/data01", {}, {});
});
// Loosely based on this ngTable demo...
// http://bazalt-cms.com/ng-table/example/6
var App2 = angular.module('taskTable', ['ngRoute', 'api_main',
'ngTable']);
// Need to change AngularJS symbols when using flask + Jinja
App2.config(function($interpolateProvider) {
$interpolateProvider.startSymbol('[[');
$interpolateProvider.endSymbol(']]');
});
App2.controller('tableCntl', function($scope, $filter, restDemo, ngTableParams) {
var data = restDemo.query(); // HTTP GET for REST service
// Set up task table parameters
$scope.tableParams = new ngTableParams({
page: 1, // show first page
count: 10, // count per page
total: data.length,
sorting: {
Column01: 'asc',
Column02: 'asc',
Column03: 'asc'
},
filter: {
Column01: "",
Column02: "",
Column03: "",
}
}, {
getData: function($defer, params) {
// use build-in angular filter
var orderedData = params.filter() ?
$filter('filter')(data, params.filter()) :
data;
//sorting
orderedData = params.sorting() ?
$filter('orderBy')(orderedData, params.orderBy()) :
orderedData;
// store filtered data as $scope.words
$scope.words = orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count());
params.total(orderedData.length); // set total for recalc pagination
$defer.resolve($scope.words);
$defer.resolve(data.result);
}
});
});
</script>
<!-- Custom footer content here -->
</footer>
</html>
[{"Column02": "shines", "Column03": "paycheck", "Column01": "days"},
{"Column02": "erg", "Column03": "gag", "Column01": "emotion's"},
{"Column02": "Chris", "Column03": "Poznan's", "Column01": "treasure's"},
{"Column02": "presentiments", "Column03": "Austerlitz's", "Column01": "suppression's"},
{"Column02": "leopards", "Column03": "slosh's", "Column01": "upturned"},
{"Column02": "uncaring", "Column03": "cosmetics", "Column01": "symmetry"},
{"Column02": "guesser's", "Column03": "lapped", "Column01": "retrogressed"},
{"Column02": "Kurd", "Column03": "wryest", "Column01": "cicadas"},
{"Column02": "cantered", "Column03": "encrustation's", "Column01": "beyond"},
{"Column02": "flybys", "Column03": "poesying", "Column01": "physician's"},
{"Column02": "fun", "Column03": "Delaware's", "Column01": "destructiveness"},
{"Column02": "scramblers", "Column03": "gestates", "Column01": "acoustics"},
{"Column02": "redesigning", "Column03": "cubits", "Column01": "Enterprise"},
{"Column02": "phonograph's", "Column03": "haloed", "Column01": "upsurge"},
{"Column02": "Michelson", "Column03": "Pansy", "Column01": "McCoys"},
{"Column02": "adieu", "Column03": "Dido", "Column01": "ligaturing"},
{"Column02": "osprey's", "Column03": "expressiveness's", "Column01": "Starr"},
{"Column02": "patent's", "Column03": "therapeutically", "Column01": "brasher"},
{"Column02": "enfranchise", "Column03": "idolized", "Column01": "criticized"},
{"Column02": "Angel", "Column03": "wryest", "Column01": "drum"},
{"Column02": "overstaying", "Column03": "tranquillized", "Column01": "alacrity"},
{"Column02": "underachievers", "Column03": "minority", "Column01": "Brigham's"},
{"Column02": "lobotomy's", "Column03": "filament's", "Column01": "scoldings"},
{"Column02": "original", "Column03": "muskmelon's", "Column01": "financially"},
{"Column02": "flagon's", "Column03": "vapidness", "Column01": "Klaus's"},
{"Column02": "dhotis", "Column03": "fleeter", "Column01": "jugulars"},
{"Column02": "shanty", "Column03": "profiteer's", "Column01": "disbelief"},
{"Column02": "bureaucracies", "Column03": "flashier", "Column01": "refrigerating"},
{"Column02": "betrayal's", "Column03": "hindquarters", "Column01": "faze"},
{"Column02": "Poland", "Column03": "cobbler", "Column01": "kidnaped"}]
I'm using...
What I already tried
None of these things seemed to have an effect on the problem:
null
instead of empty strings in my filter, as suggested by Sander Elias
If I inline the json data inside the <script>
block instead of making an ajax json REST service call, the table populates correctly when the page loads, but that really doesn't help since the data changes from time to time.
Your data
are asynchronously fetched but you use it synchronously. Then first getData
call uses unresolved data, which means no data at all.
Typing a character seems to recall getData
with, this time, resolved data
. That would explain data showing on first key typed.
To wait for data being fetched, implement ngTable
call in such a callback:
/* there, data are not fetched */
data.$promise.then(function (data) {
/* there data are fetched, work with it */
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With