Understanding defer sorting example in ng-table demo - javascript

I'm trying to use the example shown here
http://bazalt-cms.com/ng-table/example/3
Here are some snippets of it:
<table ng-table="tableParams" class="table">
<tr ng-repeat="user in $data">
<td data-title="'Name'" sortable="'name'">
{{user.name}}
</td>
<td data-title="'Age'" sortable="'age'">
{{user.age}}
</td>
</tr>
</table>
This the data initialization at the js script:
var data = [{name: "Moroni", age: 50},
{name: "Tiancum", age: 43},
{name: "Jacob", age: 27},
{name: "Nephi", age: 29},
{name: "Enos", age: 34},
{name: "Tiancum", age: 43},
{name: "Jacob", age: 27},
{name: "Nephi", age: 29},
{name: "Enos", age: 34},
{name: "Tiancum", age: 43},
{name: "Jacob", age: 27},
{name: "Nephi", age: 29},
{name: "Enos", age: 34},
{name: "Tiancum", age: 43},
{name: "Jacob", age: 27},
{name: "Nephi", age: 29},
{name: "Enos", age: 34}];
There are two things I can not understand:
1. Why is there a $ sign in the ng-repeat clause? <tr ng-repeat="user in $data">
If i take the $ of, the example doesn't work.
I don't understand the $defer part in the example. I tried reading the docs and view examples about what defer does and just didn't get it.
How calling:
$defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));
}
effects the scope data parameter and is it related to the fact it has a dollar sign at the html (as i mentioned at the previous question)?

Name of array holding elements for table have nothing to do with
with actual object exposed to $scope. You can change occurrence of
'data' in DemoCtrl and you will see it.
$data is object exposed to the ng-table directive scope after resolving promise in getData method.
I still have problems with $defers. Your question motivated me to fill knowledge gap:
Promises in AngularJS and where to use them?
AngularJS Promises - The Definitive Guide

Related

How to output an array in Javascript like a social media feed?

I'm using React for my application and I've put my data (objects) into an array. Is there a way to output my data (array of objects) that loads all at once (such as Twitter, Instagram, Facebook)?
Currently I'm using a for loop where it loads one by one from my latest post to the end.
Here's a sample for loop to demonstrate.
var myArray = [
{name: 'Dwayne', age: 28},
{name: 'Rob', age: 32},
{name: 'Marie', age: 22},
{name: 'Sarah', age: 40},
{name: 'Emma', age: 29},
{name: 'James', age: 30}
];
for (var i = myArray.length - 1; i >= 0; i--){
console.log(myArray[i].name, myArray[i].age);
}
Here's an example of using map to generate a <p/> element with name and age inside it.
render(){
const myArray = [
{name: 'Dwayne', age: 28},
{name: 'Rob', age: 32},
{name: 'Marie', age: 22},
{name: 'Sarah', age: 40},
{name: 'Emma', age: 29},
{name: 'James', age: 30}
];
return(
<div>
{myArray.map((item, index) => (
<p key={`${item.name}-${index}`}>
Name:{item.name}, Age:{item.age}
</p>
))}
</div>
)
}
The above code would output
<div>
<p>Name:Dwayne, Age:28</p>
<p>Name:Rob, Age:32</p>
<p>Name:Marie, Age:22</p>
<p>Name:Sarah, Age:40</p>
<p>Name:Emma, Age:29</p>
<p>Name:James, Age:30</p>
</div>

Angular JS ng-table errors TypeError: newParams reload is not a function and 10 digest iterations reached, ABort

I am using the open source Angular JS theme SB Admin i completed lot of work on this. But i am want to add Angular JS ng-table it is throwing me following erros:
TypeError: a.reload is not a function
at Object.fn (ng-table.min.js:3)
at h.$digest (angular.min.js:106)
at h.$apply (angular.min.js:109)
at f (angular.min.js:71)
at F (angular.min.js:75)
at XMLHttpRequest.x.onreadystatechange (angular.min.js:76)
Error: [$rootScope:infdig] http://errors.angularjs.org/1.2.16/$rootScope/infdig?p0=10&p1=%5B%5B%22fn%3…C%22%3A%5B%5D%7D%3B%20oldVal%3A%20%7B%5C%22data
EDIT:: As the theme code is big, i created a small Fiddle script with only required things, i am getting the above and also, "newParams.reload is not a function and 10 $digest() iterations reached. Aborting!" errors.
Please check this Fiddle . Table seems to be important for my project, any advise is helpful.
As i searched a lot for 2 days to find solution to this problem in many forums, i am unable to find and thanks to few people, who came along to sort this out.
Any way, i finded out the actual problem it is simple, "When you are using NgTableParams, please didnot use the 'NgTableParams' variable as a scope variable, always try to use it as class variable".
I didn’t know the reason, why we have to use class variable. But from my point of view (my conclusion is based on errors), as scope variables in Angular JS are exposed to watchers and go for the digest cycle, it is giving this problem.
Following example works awesome :
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width">
<link rel="stylesheet" href="./dist/bootstrap.min.css">
<link rel="stylesheet" href="./dist/bootstrap-theme.min.css">
<!--[if lt IE 9]>
<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
<![endif]-->
<script src="./dist/angular.js"></script>
<script src="./dist/ng-table.js"></script>
<link rel="stylesheet" href="./dist/ng-table.css">
<body ng-app="main">
<div ng-controller="DemoCtrl as demo">
<table ng-table="demo.tableParams" class="table" export-csv="csv" ng-table-columns-binding="demo.columns">
<tr ng-repeat="user in $data">
<td data-title="'Name'" ng-if="true">
{{user.name}}
</td>
<td data-title="'Age'" ng-if="true" filter="{ age: 'text'}">
{{user.age}}
</td>
</tr>
</table>
<!-- <table ng-table="demo.tableParams" class="table" show-filter="true">
<tr ng-repeat="user in $data">
<td title="'Name'" filter="{ name: 'text'}" sortable="'name'">
{{user.name}}</td>
<td title="'Age'" filter="{ age: 'number'}" sortable="'age'">
{{user.age}}</td>
</tr>
</table>
--></div>
<script>
var app = angular.module('main', ['ngTable']).
controller('DemoCtrl', function($scope, NgTableParams ) {
var self = this;
$scope.data = [{name: "Moroni", age: 50},
{name: "Tiancum", age: 43},
{name: "Jacob", age: 27},
{name: "Nephi", age: 29},
{name: "Enos", age: 34},
{name: "Tiancum", age: 43},
{name: "Jacob", age: 27},
{name: "Nephi", age: 29},
{name: "Enos", age: 34},
{name: "Tiancum", age: 43},
{name: "Jacob", age: 27},
{name: "Nephi", age: 29},
{name: "Enos", age: 34},
{name: "Tiancum", age: 43},
{name: "Jacob", age: 27},
{name: "Nephi", age: 29},
{name: "Enos", age: 34}];
self.tableParams = new NgTableParams({
}, {
dataset: $scope.data
});
});
</script>
</body>
</html>
by initialise $scope.tableParams = new NgTableParams({}, { dataset:[] }) worked for me
thank you

ng-table sorting not working

I have created an application using ng-table, the application is working fine which had generated table using ng-table. The problem which i am facing is that the table sorting is not working. My code is as given below
Working Demo
html
<table ng-table="tableParams" class="table">
<tr ng-repeat="user in myValues">
<td data-title="'Name'" sortable="'name'">
{{user.name}}
</td>
<td data-title="'Age'" sortable="'age'">
{{user.age}}
</td>
</tr>
</table>
script
var app = angular.module('main', ['ngTable']).
controller('DemoCtrl', function($scope, $filter, ngTableParams) {
$scope.myValues = [{name: "Moroni", age: 50},
{name: "Tiancum", age: 43},
{name: "Jacob", age: 27},
{name: "Nephi", age: 29},
{name: "Enos", age: 34},
{name: "Tiancum", age: 43},
{name: "Jacob", age: 27},
{name: "Nephi", age: 29},
{name: "Enos", age: 34},
{name: "Tiancum", age: 43},
{name: "Jacob", age: 27},
{name: "Nephi", age: 29},
{name: "Enos", age: 34},
{name: "Tiancum", age: 43},
{name: "Jacob", age: 27},
{name: "Nephi", age: 29},
{name: "Enos", age: 34}];
$scope.tableParams = new ngTableParams({
sorting: {
name: 'asc'
}
}, {
getData: function($defer, params) {
$defer.resolve($filter('orderBy')($scope.myValues, params.orderBy()));
}
});
});
$defer.resolve($filter('orderBy')($scope.myValues, params.orderBy()));
will create a new sorted array but will not change $scope.myValues.
So either, you set $scope.myValues to the sorted array each time:
$scope.myValues = $filter('orderBy')($scope.myValues, params.orderBy());
$defer.resolve($scope.myValues);
Or use $data in ng-repeatinstead of myValues:
<tr ng-repeat="user in $data">
In your HTML you need to update the myValues to be $data.
<tr ng-repeat="user in $data">
Plunker
You're writing to $scope.myValues, and using that in the ng-repeat directive - but you're sorting the data only in getData() on the table params object.
getData() doesn't ever change $scope.myValues, it only uses it to return a sorted array. What you really want to do is:
Don't make the full dataset available on the scope, but store it in a variable inside the controller:
var data = [{name: "Moroni", age: 50}, ...]
$defer.resolve($filter('orderBy')(data, params.orderBy()));
Use $data inside the HTML code, because this is what accesses getData():
<tr ng-repeat="user in $data">

sorting feature in ngTable using Jasmine Testing

I have created an application using ng-table , the application is working fine but i don'nt know how to write a test case for that sorting and getData.
Can anyone please tell me some solution for testing that functionality
My code is as given below
jasmine test case
describe('Testing Controllers', function() {
describe('Testing WorkController Controller', function() {
var WorkController, $scope;
beforeEach(module('wsd'));
beforeEach(inject(function($controller, $rootScope) {
$scope = $rootScope.$new();
WorkController = $controller('WorkController', {
$rootScope: $rootScope,
$scope: $scope,
ngTableParams : ngTableParams,
$filter: $filter
});
}));
it('should tableParams when tableParams is called', function() {
});
});
});
workstation/main.js
angular.module('wsd.workstations', [])
.controller('WorkController', function($rootScope, $scope, $filter, ngTableParams)
{
$scope.myValues = [{name: "Moroni", age: 50},
{name: "Tiancum", age: 43},
{name: "Jacob", age: 27},
{name: "Nephi", age: 29},
{name: "Enos", age: 34},
{name: "Tiancum", age: 43},
{name: "Jacob", age: 27},
{name: "Nephi", age: 29},
{name: "Enos", age: 34},
{name: "Tiancum", age: 43},
{name: "Jacob", age: 27},
{name: "Nephi", age: 29},
{name: "Enos", age: 34},
{name: "Tiancum", age: 43},
{name: "Jacob", age: 27},
{name: "Nephi", age: 29},
{name: "Enos", age: 34}];
$scope.tableParams = new ngTableParams({
sorting: {
name: 'asc'
}
}, {
getData: function($defer, params) {
$scope.myValues = $filter('orderBy')($scope.myValues, params.orderBy());
$defer.resolve($scope.myValues);
}
});
$scope.searchDocuments = function()
{
// some other logic
};
});
Update 2
I have done like this for testing, but getting
<failure type="">TypeError: &apos;undefined&apos; is not a function (evaluating &apos;$defer.resolve($scope.myValues)&apos;)
test cases
it('should check tableParams getData sorting', inject(function($q) {
var deferred = $q.defer();
var promise = deferred.promise;
promise.then(function(result) {
expect(result).toEqual(expectedResult);
});
$scope.myValues = [{name: "Moroni", age: 50},
{name: "Tiancum", age: 43},
{name: "Jacob", age: 27},
{name: "Nephi", age: 29},
{name: "Enos", age: 34},
{name: "Tiancum", age: 43},
{name: "Jacob", age: 27},
{name: "Nephi", age: 29},
{name: "Enos", age: 34},
{name: "Tiancum", age: 43},
{name: "Jacob", age: 27},
{name: "Nephi", age: 29},
{name: "Enos", age: 34},
{name: "Tiancum", age: 43},
{name: "Jacob", age: 27},
{name: "Nephi", age: 29},
{name: "Enos", age: 34}];
$scope.getData(promise, $scope.tableParams );
}));
You could:
Declare getData function on controller's $scope, thus making it available in your test:
$scope.tableParams = new ngTableParams({
sorting: {
name: 'asc'
}
}, {
getData: $scope.getData
});
$scope.getData = function($defer, params) {
$scope.myValues = $filter('orderBy')($scope.myValues, params.orderBy());
$defer.resolve($scope.myValues);
}
Inject $q in beforeEach().
Create a promise object using $q.
Assign some $scope.myValues for your unit test.
Declare a variable containing your expected result - that is your sorted $scope.myValues array. Then:
promise.then(function(result){
expect(result).toEqual(expectedResult);
}
$scope.getData(deferred , $scope.tableParams);

Passing java script function result to Angular ng-table

I have Angular ng-table where I load Json data to $data variable and display in the table.
function ngTable(){
var app = angular.module('main', ['ngTable']).
controller('DemoCtrl', function($scope, ngTableParams) {
var data = [{name: "Moroni", age: 50},
{name: "Tiancum", age: 43},
{name: "Jacob", age: 27},
{name: "Nephi", age: 29},
{name: "Enos", age: 34},
{name: "Tiancum", age: 43},
{name: "Jacob", age: 27},
{name: "Nephi", age: 29},
{name: "Enos", age: 34},
{name: "Tiancum", age: 43},
{name: "Jacob", age: 27},
{name: "Nephi", age: 29},
{name: "Enos", age: 34},
{name: "Tiancum", age: 43},
{name: "Jacob", age: 27},
{name: "Nephi", age: 29},
{name: "Enos", age: 34}];
$scope.tableParams = new ngTableParams({
page: 1, // show first page
count: 10 // count per page
}, {
total: data.length, // length of data
getData: function($defer, params) {
$defer.resolve(data.slice((params.page() - 1) * params.count(), params.page() * params.count()));
}
});
});
}
Additionally I have Java Script function returning some other Json data - function is called on button click.
function ReturnJson() {
var json = [];
$('body').on('click','button#test', function(){
var id = $(this).attr("value").val();
json = id;
});
return json;
}
How do I replace var data content with ReturnJson() every time on button click action ?
Simple assignment will work, but remember to reload the grid:
$scope.loadData = function () {
$scope.data = $scope.ReturnJson();
$scope.tableParams.reload();
}
$scope.ReturnJson = function () {
var json = [{name: "bb", age: 200},{name: "aaa", age: 100}];
return json;
}
Here is a working demo: http://plnkr.co/edit/Jw41uCmHGAfjkuoLIQor?p=preview

Categories

Resources