sorting feature in ngTable using Jasmine Testing - javascript

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);

Related

How to reload grid after every 5 seconds in angular js?

I am using angular js and using and I want to reload grid after every 5 seconds.
My angular js code for build grid is as bellow:
App.controller('NGTableCtrl', NGTableCtrl);
function NGTableCtrl($scope, $filter, ngTableParams, $resource, $timeout, ngTableDataService) {
'use strict';
// required for inner references
var vm = this;
var data = [
{name: "Moroni", age: 50, money: -10 },
{name: "Tiancum", age: 43, money: 120 },
{name: "Jacob", age: 27, money: 5.5 },
{name: "Nephi", age: 29, money: -54 },
{name: "Enos", age: 34, money: 110 },
{name: "Tiancum", age: 43, money: 1000 },
{name: "Jacob", age: 27, money: -201 },
{name: "Nephi", age: 29, money: 100 },
{name: "Enos", age: 34, money: -52.5 },
{name: "Tiancum", age: 43, money: 52.1 },
{name: "Jacob", age: 27, money: 110 },
{name: "Nephi", age: 29, money: -55 },
{name: "Enos", age: 34, money: 551 },
{name: "Tiancum", age: 43, money: -1410 },
{name: "Jacob", age: 27, money: 410 },
{name: "Nephi", age: 29, money: 100 },
{name: "Enos", age: 34, money: -100 }
];
// SELECT ROWS
vm.data = data;
vm.tableParams3 = new ngTableParams({
page: 1, // show first page
count: 10 // count per page
}, {
total: data.length, // length of data
getData: function ($defer, params) {
// use build-in angular filter
var filteredData = params.filter() ?
$filter('filter')(data, params.filter()) :
data;
var orderedData = params.sorting() ?
$filter('orderBy')(filteredData, params.orderBy()) :
data;
params.total(orderedData.length); // set total for recalc pagination
$defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));
}
});
// EXPORT CSV
var data4 = [{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}];
vm.tableParams4 = new ngTableParams({
page: 1, // show first page
count: 10 // count per page
}, {
total: data4.length, // length of data4
getData: function($defer, params) {
$defer.resolve(data4.slice((params.page() - 1) * params.count(), params.page() * params.count()));
}
});
// SORTING
vm.tableParams = new ngTableParams({
page: 1, // show first page
count: 10, // count per page
sorting: {
name: 'asc' // initial sorting
}
}, {
total: data.length, // length of data
getData: function($defer, params) {
// use build-in angular filter
var orderedData = params.sorting() ?
$filter('orderBy')(data, params.orderBy()) :
data;
$defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));
}
});
// FILTERS
vm.tableParams2 = new ngTableParams({
page: 1, // show first page
count: 10, // count per page
filter: {
name: '',
age: ''
// name: 'M' // initial filter
}
}, {
total: data.length, // length of data
getData: function($defer, params) {
// use build-in angular filter
var orderedData = params.filter() ?
$filter('filter')(data, params.filter()) :
data;
vm.users = orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count());
params.total(orderedData.length); // set total for recalc pagination
$defer.resolve(vm.users);
}
});
}
If I am using setTimeout inside the function then it is not refreshing new values.
Any help/suggestion would be appreciated.
Not sure exactly which function you need to wrap and execute every 5 seconds, but you can use the Angular Interval service.
Simply inject $interval to your controller and do this:
$interval(functionToRerun, 5000);
This way it will rerun your function every 5 seconds.
A quick note on why setTimeout didn't refresh the values on the view: setTimeout is not an Angular function, so Angular was not aware of the change, hence the $digest cycle did not run and the changes were not reflected.
Try.. $interval
$interval(function () {
loadData();
}, duration)
More about this at.. https://docs.angularjs.org/api/ng/service/$interval

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">

Understanding defer sorting example in ng-table demo

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

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

How can I update a row in a javascript array based on a key value?

I have an array of data like this:
var nameInfo = [{name: "Moroni", age: 50},
{name: "Tiancum", age: 43},
{name: "Jacob", age: 27},
{name: "Nephi", age: 29},
{name: "Enos", age: 34}];
If I have an object like this:
var nameInfo = {name: "Moroni", age: 51};
Is there a simple way that I can update the variable nameInfo. The key
between these is the name column. I know there is a way that I could
do this by searching for the row, removing and adding but I would like
to have a way to do this where I updated the row. Note that if it helps I do have underscore.js loaded.
Easiest way is to just loop over and find the one with a matching name then update the age:
var newNameInfo = {name: "Moroni", age: 51};
var name = newNameInfo.name;
for (var i = 0, l = nameInfo.length; i < l; i++) {
if (nameInfo[i].name === name) {
nameInfo[i].age = newNameInfo.age;
break;
}
}
JSFiddle Example
Using underscore you can use the _.find method to do the following instead of the for loop:
var match = _.find(nameInfo, function(item) { return item.name === name })
if (match) {
match.age = newNameInfo.age;
}
JSFiddle Example
Edit:
You can use ES6 filter combined with arrow functions
nameInfo.filter(x => {return x.name === nametofind })[0].age = newage
You can use _.where function
var match = _.where(nameInfo , {name :nametofind });
then update the match
match[0].age = newage
var nameInfo = [{name: "Moroni", age: 50},{name: "Tiancum", age: 43},
{name: "Jacob", age: 27},{name: "Nephi", age: 29},
{name: "Enos", age: 34}
];
_.map(nameInfo, function(obj){
if(obj.name=='Moroni') {
obj.age=51; // Or replace the whole obj
}
});
This should do it. It's neat and reliable and with underscore
Using Underscore you can use _.findWhere http://underscorejs.org/#findWhere
_.findWhere(publicServicePulitzers, {newsroom: "The New York Times"});
=> {year: 1918, newsroom: "The New York Times",
reason: "For its public service in publishing in full so many official reports,
documents and speeches by European statesmen relating to the progress and
conduct of the war."}
You can use findWhere and extend
obj = _.findWhere(#songs, {id: id})
_.extend(obj, {name:'foo', age:12});
You can use the _.find method, like this:
var nameInfos = [{name: "Moroni", age: 50},
{name: "Tiancum", age: 43},
{name: "Jacob", age: 27},
{name: "Nephi", age: 29},
{name: "Enos", age: 34}];
var nameToSearch = "Moroni";
var myRecord = _.find(nameInfos, function(record){ return record.name === nameToSearch; });
Working example: http://jsfiddle.net/9C2u3/
var match = _.findWhere(nameInfo , {name :nametofind });
match.age = newage
A staright forward using lodash's find() function,
var nameInfo = [{name: "Moroni", age: 50},
{name: "Tiancum", age: 43},
{name: "Jacob", age: 27},
{name: "Nephi", age: 29},
{name: "Enos", age: 34}];
var objToUpdate = _.find(nameInfo, {name: "Moroni"});
if(objToUpdate) objToUpdate.age = 51;
console.log(nameInfo); // Moroni age will be 51;
Note: If there are multiple Moroni objects, _.find can fetch the first match only.

Categories

Resources