ngTable Detect Sorting in View - angularjs

Is there a way to detect whether or not ngTable currently has a sort applied? Binding to the sorting table parameter does not work correctly.
<!--- Never shows---->
<label ng-if="tableParams.$params.sorting === {}">No sort applied</label>
<!--- Never shows---->
<label ng-if="tableParams.$params.sorting() === {}">No sort applied</label>
Oddly enough this simple binding example works as expected:
<label>settings={{ tableParams.$params.sorting }}</label>
When a sort is applied a value of: {"sortColumn":"sortDirection"} appears:
{"Id":"desc"}
or if a sort is not applied:
{}
Any help would be appreciated.

You can do something like this:
var app = angular.module('app', []);
app.controller('myController', function($scope) {
$scope.angular = angular;
$scope.tableParams = {
$params: {
sorting: {}
}
};
$scope.sort = function() {
$scope.tableParams.$params.sorting[1] = true;
};
$scope.unsort = function() {
delete $scope.tableParams.$params.sorting[1];
};
$scope.isSorted = function(tableParams) {
return !angular.equals({}, tableParams.$params.sorting);
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="myController">
<div ng-show="!isSorted(tableParams)">No sort applied</div>
<button ng-click=sort()>sort</button>
<button ng-click=unsort()>unsort</button>
<br>{{ tableParams }}
</div>
</div>
You can also make the angular object accessible in templates by making it available to the scope.
var app = angular.module('app', []);
app.controller('myController', function($scope) {
$scope.angular = angular;
$scope.tableParams = {
$params: {
sorting: {}
}
};
$scope.sort = function() {
$scope.tableParams.$params.sorting[1] = true;
};
$scope.unsort = function() {
delete $scope.tableParams.$params.sorting[1];
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="myController">
<div ng-show="angular.equals({}, tableParams.$params.sorting)">No sort applied</div>
<div>
<button ng-click=sort()>sort</button>
<button ng-click=unsort()>unsort</button>
</div>
<div><br>{{ tableParams }}</div>
</div>
</div>
var app = angular.module('app', []);
app.controller('myController', function($scope) {
$scope.angular = angular;
$scope.tableParams = {
$params: {
sorting: {}
}
};
$scope.sort = function() {
$scope.tableParams.$params.sorting[1] = true;
};
$scope.unsort = function() {
delete $scope.tableParams.$params.sorting[1];
};
$scope.strictlyEqualsEmptyObject = function(obj) {
return {} === obj;
};
$scope.equalsEmptyObject = function(obj) {
return {} == obj;
};
$scope.angularEqualsEmptyObject = function(obj) {
return angular.equals({}, obj);
};
$scope.objectKeysLength = function(obj) {
return Object.keys(obj).length === 0;
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="myController">
<div>{{ tableParams }}</div>
<div>
<button ng-click=sort()>sort</button>
<button ng-click=unsort()>unsort</button>
</div>
<table>
<th>Not sorted check using:</th>
<tr>
<td>strict </td>
<td>{{ strictlyEqualsEmptyObject(tableParams.$params.sorting) }}</td>
</tr>
<tr>
<td>equals </td>
<td>{{ equalsEmptyObject(tableParams.$params.sorting) }}</td>
</tr>
<tr>
<td>angular </td>
<td>{{ angularEqualsEmptyObject(tableParams.$params.sorting) }}</td>
</tr>
<tr>
<td>Object.keys </td>
<td>{{ objectKeysLength(tableParams.$params.sorting) }}</td>
</tr>
</table>
</div>
</div>

Related

unable to repeat collections value using angularjs ng-repeat

I was trying to do a webAPI call from AnguarJs. I receive success response "data" object perfectly.When it is passed to HTML page under "ng-repeat" it is not displaying any records.
Following is the one not working
<tr ng-repeat = "cust in Customers">
<td>{{ cust.CustomerName }} </td>
<td>{{ cust.CustomerCode }}</td>
<td>{{ cust.CustomerAmount }}</td>
<td>{{ cust.ProcessDate }}</td>
</tr>
But if i put in this way it will display the 0th index records
<tr ng-repeat = "cust in Customers">
<td>{{cust[0].CustomerName }} </td>
<td>{{cust[0].CustomerCode }}</td>
<td>{{cust[0].CustomerAmount}}</td>
<td>{{cust[0].ProcessDate }}</td>
</tr>
Note : In the below code i split up files in different javascript files and referred in the main html page.Just for your information.
My Fiddle Link : JsFiddle
Please help me in resolve it.
function Utility(){
this.ApplicationVersion = "0.0.1";
this.ApplicationName = "AngularJs First Project";
this.getDate = function () {
var dt = new Date();
return dt.toDateString();
}
this.IsEmpty = function (value) {
if (value.length == 0) {
return false;
}
else {
return true;
}
}
}
function Customer(utility) {
this.CustomerCode = "1001";
this.CustomerName = "Ragu";
this.CustomerAmount = 100;
this.CalculateDiscount = function()
{
return 10;
}
this.ProcessDate = utility.getDate();
}
function Factory()
{
return {
CreateCustomer: function (utility) {
return new Customer(utility);
}
}
}
/// <reference path="Utility.js" />
/// <reference path="Customer.js" />
var myApp = angular.module("myApp", []);
myApp.controller("BindingCode",BindingCode);
myApp.factory("Factory", Factory);
myApp.service("UtilityObj", Utility);
function BindingCode($scope, UtilityObj, Factory,$http)
{
$scope.Customer = Factory.CreateCustomer(UtilityObj);
$scope.Customers = [];
$scope.Utility = UtilityObj;
$scope.Customer.CustomerCode = "1002";
$scope.Customer.CustomerName = "Raman";
$scope.Customer.ProcessDate = UtilityObj.getDate();
$scope.Color = "blue";
$scope.$watch("Customer.CustomerAmount", function () {
if ($scope.Customer.CustomerAmount < 1000) {
$scope.Color = "Red";
}
else {
$scope.Color = "Green";
}
});
$scope.Submit = function()
{
debugger
if ($scope.Utility.IsEmpty($scope.Customer.CustomerAmount)) {
debugger
$http.post("http://localhost:61860/api/Customer", $scope.Customer).then(function(data){
$scope.Customers = data;
debugger
$scope.Customer = {}; // clearing the record
},
function(data)
{
debugger
alert("inside error http call" + data);
}
);
//$http.post("http://localhost:61860/api/Customer", $scope.Customer).
// success(function (data) {
// debugger
// $scope.Customers = data;
// $scope.Customer = {};
//});
}
else {
alert("No Proper Date");
}
}
}
<script src="Scripts/angular.js"></script>
<script src="Customer.js"></script>
<script src="Utility.js"></script>
<script src="app.js"></script>
<body ng-app="myApp">
<div id="CustScreen" ng-controller="BindingCode">
CustomerCode : <input type="text" ng-model="Customer.CustomerCode" id="txtCustomercode" /> <br />
CustomerName : <input type="text" ng-model="Customer.CustomerName" id="txtCustomerName" /> <br />
CustomerDate : <input type="text" ng-model="Customer.ProcessDate" id="txtCustomerDate" /> <br />
CustomerAmount : <input type="text" style="background-color:{{ Color }}" ng-model="Customer.CustomerAmount" id="txtCustomerAmount" /><br />
<br />
{{ Customer.CustomerCode }} <br />
{{ Customer.CustomerName }} <br />
{{ Customer.ProcessDate }}<br />
{{ Customer.CustomerAmount}} <br />
<input type="submit" ng-click="Submit()" id="Submit" />
<table>
<tr>
<td>Name</td>
<td>Code</td>
<td>Amount</td>
<td>ProcessDate</td>
</tr>
<tr ng-repeat = "cust in Customers">
<td>{{cust.CustomerName }} </td>
<td>{{cust.CustomerCode }}</td>
<td>{{cust.CustomerAmount}}</td>
<td>{{cust.ProcessDate }}</td>
</tr>
</table>
</div>
</body>
Try this
$scope.Customers=data[0];

Angular in electron, slow rendering for large json

I'm currently learning Electron and using AngularJS.
I've my REST api in node and express and my database is MongoDB.
this is my route
router.get('/branch/:branch',function (req,res,next) {
var br = req.params.branch;
var final = [];
db.collection('users').find({"branch": br}, function (err, docs) {
docs.forEach(function (ele) {
console.log(ele['fir_id']);
final.push(ele['fir_id']);
})
db.punch_coll.find(function (err, docs) {
var d = [];
console.log(final);
docs.forEach(function (ele) {
console.log(ele['fir_id']);
if(final.includes(parseInt(ele['fir_id']))) {
ele['date'] = ele['date'].toDateString();
ele['punch_in'] = ele['punch_in'].substring(0, 8);
ele['punch_out'] = ele['punch_out'].substring(0, 8);
d.push(ele);
}
console.log(d);
})
console.log(d);
res.send(d);
})
});
});
punch_coll document
{
_id: 58e21075e0c6800ce8b08d92,
fir_id: '4',
date: 'Mon Apr 03 2017',
punch_in: '14:35:57',
punch_out: ''
}
user document
{
_id: 58e20ee0e0c6800ce8b08d82,
name: 'A B C',
fir_id: 1,
branch: 'CSE',
year: 'SE'
}
HTML and Angular Controller Script
<body ng-app="myApp" ng-controller="myCtrl">
<form class="pure-form">
<strong>Enter FIR-ID</strong> <input type="text" ng-model="fid" ng-
change="change()" class="pure-input-rounded">
</form>
</br>
<div class="pure-g">
<div class="pure-u-8-24" style="border-style: solid;border-
color:lightgrey;">
<header class="w3-container w3-light-grey">
<h2>Fir ID :- {{fid}}</h2>
<h3>Name :- {{user[0].name}} </h3>
</header>
<div class="w3-container">
<h2>Branch :- {{user[0].branch}} </h2>
<hr>
<h2>Academic Year :- {{user[0].year}} </h2>
</div>
</div>
</div>
<form class="pure-form">
<select id="state" ng-model="branch" ng-change="changeBranch()">
<option>CSE</option>
<option>MECH</option>
<option>CIVIL</option>
<option>ENTC</option>
</select>
</form>
<!-- <h2>Fir ID :- {{fid}}</h2>
<h2>Name :- {{user[0].name}} </h2>
<h2>Branch :- {{user[0].branch}} </h2>
<h2>Academic Year :- {{user[0].year}} </h2> -->
<div style="right:0;top:0;position:absolute;font-size:20px;">
<table class="pure-table pure-table-horizontal">
<thead>
<tr>
<th>Fir ID</th>
<th>Date</th>
<th>Punch In</th>
<th>Punch Out</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="x in name">
<td>{{ x.fir_id }}</td>
<td>{{ x.date }}</td>
<td>{{ x.punch_in }}</td>
<td>{{ x.punch_out }}</td>
</tr>
</tbody>
</table>
</div>
</body>
<script>
// You can also require other files to run in this process
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope,$http) {
$scope.name;
$scope.user;
$scope.fid;
$scope.branch='CSE';
$scope.change = function() {
//get punches for specific fir_id
$http.get('http://localhost:3000/users/'+$scope.fid)
.then(function(response) {
$scope.user=response.data;
})
//get punches for specific fir_id
$http.get('http://localhost:3000/punch/'+$scope.fid)
.then(function(response) {
console.log(response.status);
$scope.name=response.data;
}, function errorCallback(response) {
$scope.name=null;
});
};
$scope.changeBranch = function(){
//get record as per branch
$http.get('http://localhost:3000/branch/'+$scope.branch)
.then(function(response) {
console.log(response.status);
$scope.name=response.data;
}, function errorCallback(response) {
$scope.name=null;
});
};
});
The table is rendering slow for large json takes 1second it's like it's lagging.
I'm new to this so of course I'm doing something horrible. I think the way I'm using that async functions are bad also but dont know whats making it slow foreach or anything else.
So, after replacing foreach with simple for loop it solved the problem but I don't know whats the exact reason. Anyone had same problem?

Issues converting "controller as" syntax to classic $scope

I have had major issues trying to convert my code from "controller as/this" syntax to classic $scope syntax, without breaking the code. I tried simply replacing "this" with $scope and removing the "controller as" assignments for both controllers, with no luck. I have created a jsfiddle for this with the controller as/this syntax so you can see how it should be working correctly prior to converting the syntax to $scope. https://jsfiddle.net/6zk9vujo/6/
This is another jsfiffle showing the broken code, when I simply replace _this with $scope and remove the controller as assignments in the html https://jsfiddle.net/6zk9vujo/12/ Thank you for your help in advance.
HTML
<div ng-app="app">
<div ng-controller="mainController as main">
<h2>
Main Controller
</h2>
<div>
<table>
<tr>
<td>Item</td>
<td>Price</td>
<td>Quantity</td>
<td></td>
</tr>
<tr ng-repeat="product in main.items">
<td>{{product.name}}</td>
<td>{{product.price | currency}}</td>
<td>
<button ng-click="main.increaseItemAmount(product)">
+
</button>
{{product.quantity}}
<button ng-click="main.decreaseItemAmount(product)">
-
</button>
<button ng-click="main.addToCart(product)">
Add to Cart
</button>
</td>
</tr>
</table>
</div>
</div>
<div ng-controller="cartController as cart">
<h2>
Cart Controller
</h2>
<div>
<table>
<tr>
<td>Item</td>
<td>Price</td>
<td>Quantity</td>
<td></td>
</tr>
<tr ng-repeat="product in cart.cartStorage.items">
<td>{{product.name}}</td>
<td>{{product.price | currency}}</td>
<td>
<button ng-click="cart.increaseItemAmount(product)">
+
</button>
{{product.quantity}}
<button ng-click="cart.decreaseItemAmount(product)">
-
</button>
<button ng-click="cart.removeFromCart(product)">
Remove from Cart
</button>
</td>
</tr>
</table>
</div>
</div>
</div>
JAVASCRIPT
angular.module('app', [])
.factory('cartStorage', function() {
var _cart = {
items: []
};
var service = {
get cartItems() {
return _cart;
}
}
return service;
})
.controller('mainController', function(cartStorage) {
var _this = this;
_this.cartStorage = cartStorage.cartItems;
_this.items = [{
name: 'Apple',
price: 2.5,
quantity: 1
}];
_this.addToCart = function(product) {
_this.cartStorage.items.push(product);
product.addedToCart = true;
}
_this.increaseItemAmount = function(product) {
product.quantity++;
product.showAddToCart = true;
}
_this.decreaseItemAmount = function(item) {
product.quantity--;
if (product.quantity <= 0) {
product.quantity = 0;
product.addedToCart = false;
product.showAddToCart = false;
var itemIndex = _this.cartStorage.items.indexOf(product);
if (productIndex > -1) {
_this.cartStorage.items.splice(productIndex, 1);
}
} else {
product.showAddToCart = true;
}
}
})
.controller('cartController', function(cartStorage) {
var _this = this;
_this.cartStorage = cartStorage.cartItems;
_this.increaseItemAmount = function(item) {
product.quantity++;
}
_this.decreaseItemAmount = function(item) {
item.quantity--;
if (item.quantity <= 0) {
item.quantity = 0;
item.addedToCart = false;
item.showAddToCart = false;
var productIndex = _this.cartStorage.items.indexOf(item);
if (productIndex > -1) {
_this.cartStorage.items.splice(productIndex, 1);
}
}
}
_this.removeFromCart = function(item) {
item.quantity = 0;
item.addedToCart = false;
item.showAddToCart = false;
var productIndex = _this.cartStorage.items.productOf(item);
if (productIndex > -1) {
_this.cartStorage.items.splice(productIndex, 1);
}
}
});
In the template, remove all main. and cart. and change to ng-controller="mainController" and ng-controller="cartController".
In your controllers, inject $scope and assign it to _this for easiest migration.
.controller('mainController', function($scope, cartStorage) {
var _this = $scope;
and
.controller('cartController', function($scope, cartStorage) {
var _this = $scope;
https://jsfiddle.net/6zk9vujo/10/
Alternatively, just replace all _this references with $scope in your controllers.
You also have a bunch of mixed up product / item and productIndex / itemIndex variables. I've standardised them all in this fiddle as well as fixed the logic around re-adding the same product.
https://jsfiddle.net/6zk9vujo/13/
It will work if you remove the "as" syntax when you define the controller in the view: ng-controller="mainController" and ng-controller="cartController".
Edited: I made a mistake of putting the wrong fiddle link.
https://jsfiddle.net/analiza641/jr0stbLq/3/

Why is my ng-repeat not showing pulled data?

I am following an Angular tutorial where I am trying to format my code in John Papa's style guide for Angular 1.
I am currently trying to display a table of github repos from any username that is inputted into the search form. Everything else displays except for the repos.
Please find a link to the code on plunker.co -> here.
This is the html template code below:
<div ng-controller="UserController as github">
<h4>{{ github.user.name }}</h4>
{{ github.error }}
<img ng-src="{{ github.user.avatar_url }}" title="{{ github.user.name }}" />
</div>
<div class="input-field col s12">
<select ng-model="github.repoSortOrder">
<option value="+name">Name</option>
<option value="-stargazers_count">Stars</option>
<option value="+language">Language</option>
</select>
<label>Order By:</label>
</div>
<table class="col">
<thead>
<tr>
<th>Name</th>
<th>Stars</th>
<th>Language</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="'repo in github.repos | orderBy: github.repoSortOrder'">
<td>{{ repo.name }}</td>
<td>{{ repo.stargazers_count | number }}</td>
<td>{{ repo.language }}</td>
</tr>
</tbody>
</table>
<br>
Back to search
<script type="text/javascript">
$(document).ready(function() {
$('select').material_select();
});
</script>
And this is the UserController js code:
// Code goes here
(function() {
angular
.module('app.github')
.controller('UserController', ['github', '$routeParams', '$log', function UserController(github, $routeParams, $log) {
var vm = this;
var onUserComplete = function(data) {
vm.user = data;
github.getRepos(vm.user)
.then(onRepos, onError);
};
var onRepos = function(data) {
$log.info('getting data');
vm.repos = data;
$log.info('finished getting data');
};
var onError = function(reason) {
vm.error = "Boo! Could not fetch the user data!";
};
vm.username = $routeParams.username;
vm.repoSortOrder = "-stargazers_count";
github.getUser(vm.username).then(onUserComplete, onError);
}]);
}());
Lastly, this is the 'github' service as a dependancy to the controller:
(function() {
angular
.module('app.github')
.factory('github', ['$http', '$log', function github($http, $log) {
var getUser = function(username) {
return $http.get("https://api.github.com/users/" + username)
.then(function(response) {
return response.data;
});
};
var getRepos = function(user) {
$log.info('starting getRepos()');
return $http.get(user.repos_url)
.then(function(response) {
$log.info('ending getRepos()');
return response.data;
});
};
return {
getUser: getUser,
getRepos: getRepos
};
}]);
})();
May I have someones input in this please?
Thanks
AlvSovereign
This is wrapped in single quotes which angular will evaluate as a string:
<tr ng-repeat="'repo in github.repos | orderBy: github.repoSortOrder'">
It needs to be:
<tr ng-repeat="repo in github.repos | orderBy: github.repoSortOrder">
The error is on the first line. You bound the controller to only that div.
<div ng-controller="UserController as github">//here
<h4>{{ github.user.name }}</h4>
{{ github.error }}
<img ng-src="{{ github.user.avatar_url }}" title="{{ github.user.name }}" />
</div>
Putting a div around the whole thing should fix this. Along with the ng-repeat mistake mentioned below by #robj.

how to reset a filter by leaving it empty?

I have a filter on a list :
<input ng-model="searchFileName" />
<table>
<tr ng-repeat="file in folders | filter:searchFileName">
<td><a ng-click="openFolder(file.name)">{{ file.name }}</a></td>
</tr>
</table>
I would like to clear searchFileName value when I click on a result.
This is openFolder function :
$scope.openFolder = function(name) {
$scope.searchFileName = null;
$http.jsonp($scope.server + '?open=' + encodeURIComponent($scope.buildTreePath()) + '&callback=JSON_CALLBACK').success(function(data){
$scope.folders = data;
});
}
}
I can't empty my filter field, it doesn't work... Where am I wrong ?
just use:
$scope.openFolder = function(name) {
$scope.searchFileName = null;
}
var app = angular.module('app', []);
app.controller('fCtrl', function($scope) {
$scope.folders = [
{
name: "Ala"
}, {
name: "Ata"
}, {
name: "Ara"
}, {
name: "Ama"
}
];
$scope.openFolder = function(name) {
$scope.searchFileName = null;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="fCtrl">
<input ng-model="searchFileName" />
<table>
<tr ng-repeat="file in folders | filter:searchFileName">
<td><a ng-click="openFolder(file.name)">{{ file.name }}</a>
</td>
</tr>
</table>
</div>
</div>

Resources