use orderBy for value in array - angularjs

I have nested ng-repeat that extracts data from the server:
<div ng-repeat="x in result | filter:sellbox " >
<div ng-repeat="z in x.data | orderBy:'??' " >
{{x.rate_type}} to {{x.name}} {{z[1]}}
</div>
</div>
This is part of the server:
"result":[
{
"id":"BNLN_USD",
"code":"BNLN",
"name":"National Bank Of Georgia (BNLN)",
"currency":"USD",
"rate_type":"reference",
"color":"#4b4a4b",
"legendIndex":1,
"data":[
[
1473033600000,
2.2938
]
]
},
{
"id":"BAGA_USD_B",
"code":"BAGA",
"name":"Bank Of Georgia (BAGA)",
"currency":"USD",
"rate_type":"buy",
"color":"#ed7623",
"dashStyle":"shortdot",
"legendIndex":2,
"data":[
[
1473033600000,
2.25
]
]
}
z[1] is giving the value of 2.2938 and 2.25 in this segment. How do I use orderBy so that the results are ordered in decreasing order of z[1].

Since AngularJS 1.3.0-rc.5, the orderBy filter will automatically sort the array using its items if no additional parameters are provided.
<div ng-repeat="z in x.data | orderBy">{{item}}</div>

The reason you couldn't orderBy was that your data is an array of array, so you have to call a custom orderBy function.
In your controller
$scope.customOrder = function (content) {
return content.sort()[0];
}
In your HTML pass the customOrder function and pass true to make it descending
<div ng-repeat="x in result | filter:sellbox " >
<div ng-repeat="z in x.data | orderBy:customOrder:true">
{{x.rate_type}} to {{x.name}} {{z[1]}}
</div>
</div>

I managed to solve this by mapping my results:
JS:
$rootScope.bank_data = $rootScope.result.map(function(x){
return {
rate_type: x.rate_type,
name: x.name,
value :x.data[0][1]
};
})
HTML:
<input type="searchbox" ng-model="sellbox" ng-hide="buy" >
<div ng-repeat="m in bank_data | filter:sellbox | orderBy:'-value'" > {{m.rate_type}} {{m.name}} {{m.value}}</div>
This way I managed to display the array I wanted to sort and it worked just fine. Thank you everyone for helping.

Related

Angular array doesnt show the data when it has one record

I am using an angularjs array to store the record data(table rows) received by using the http.get rest API and printing using an ng-repeat. The problem is whenever there is only one record retrieved through rest API, ng-repeat doesn't print the record. ng-repeat only print the records when API retrieves more than one record.
$scope.details=[];
var lrequ = {
method: 'GET',
url: "https://example.com/execSQL?sql=mysqlquery",
headers: {
"Content-Type": "application/json"
}
}
$http(lrequ).then(function(response){
$scope.details=response.data.platform.record;
}, function(){alert("failure");});
this is my ng-repeat line,
<div class="col-lg-12" ng-repeat="dat in details | filter : { product_name : textname} as results">
What is the problem?the problem is with ng-repeat or $scope.details array?
you can use ng-if
<div ng-if="details.length ==0>
<div class="col-lg-12" ng-repeat="dat in details[0] | filter : { product_name : textname} as results">
</div>
<div ng-if="details.length > 0>
<div class="col-lg-12" ng-repeat="dat in details | filter : { product_name : textname} as results">
</div>
try this i think it would help you:
<div class="col-lg-12" ng-repeat="dat in details track by $index | filter : { product_name : textname} as results">
<span ng-show="$first">{{dat}}</span>
</div>

How to use ng-repeat to display according to starting letter of item values

I have an array with items names ranging from A-Z.
What I want to do is ng-repeat for each letter of the alphabet.
For A letters in Array:
<div ng-repeat="item in items | orderBy: 'item_name'">
{{item.item_name}}
</div>
For B letters in Array:
<div ng-repeat="item in items | orderBy: 'item_name'">
{{item.item_name}}
</div>
How can I achieve this?
You can achieve this with custom filter
<div ng-repeat="item in items | filter:criteriaMatch('z')">
{{item.name}}
</div>
<div ng-repeat="item in items | filter:criteriaMatch('A')">
{{item.name}}
</div>
and filter function like below
$scope.criteriaMatch = function(x) {
return function( item ) {
return item.name.startsWith(x);
};
};
here is Working fiddle
hope it helps you :)
You can use the groupBy filter using the angular.filter module:
<div ng-repeat="item in items | groupBy: 'item_name.substr(0,1)'">
{{item.item_name}}
</div>

How can I limit rows showing in an ng-repeat?

I have an ng-repeat that looks like this:
<div ng-repeat="subject in subjects">
<div>{{ subject.name }}</div>
</div>
Is there some way that I can limit the display of rows to rows where subject.id is less than 50 if roleId > 1 and otherwise show all rows?
$scope.roleId = 0 means no filter
$scope.roleId > 0 means filter to show only rows in $scope.subjects where subject.id is less than 50
You can accomplish this using ng-if or use a filter
<div ng-repeat="subject in subjects" ng-if="subject.id>50">
The part about the role id in question is not clear
Use Limit to Filter
<div ng-repeat="subject in subjects | limitTo:quantity">
<div>{{ subject.name }}</div>
</div>
then set the $scope.quantity in your controller based on your business logic.
Use a Custom Filter
to use a custom filter you just set a new $scope function in your controller.
$scope.yourFilter = function (items) {
// probably need some more logic but you get the idea
return items.id < 50;
};
thin in the filter it should look like this
<div ng-repeat="subject in subjects | filter:yourFilter(subjects)">
<div>{{ subject.name }}</div>
</div>
Add a filter
<div ng-repeat="subject in subjects | filter:filterFn">
<div>{{ subject.name }}</div>
</div>
And in your controller, have this function:
$scope.filterFn = function (item) {
if ($scope.roleId > 1) {
return (item.Id < 50) ? true : false;
}
else
return true;
};
If I understood your comments correctly.

Filtering and grouping with angularJS group count

Given the following data:
[
{"Id": 3, "Name":"Image1.jpg", "AssetType":0, "Grouping": {"GroupingId": 4, "Name":"Other"}},
{"Id": 7, "Name":"Document1.jpg", "AssetType":2, "Grouping": {"GroupingId": 4, "Name":"Other"}},
{"Id": 8, "Name":"Video1.jpg", "AssetType":1, "Grouping": {"GroupingId": 4, "Name":"Other"}},
{"Id": 6, "Name":"Image2.jpg", "AssetType":0, "Grouping": {"GroupingId": 1, "Name":"Facebook"}},
]
I wanted to list separate groups of assets types, so I used the following ng-repeat:
<div class="group" ng-repeat="asset in assets | filterBy : ['AssetType'] : 0 "
<b>{{ asset.Grouping.Name}}</b><br />
{{ asset.Name }}
</div>
This gets me the following:
Other
Image1.jpg
Facebook
Image2.jpg
Now, I wanted to group by the grouping name, to test if there was only one group for this asset type. If there was only one, I was not going to show the grouping name, so I added a group by to the ng-repeat statement:
<div class="group" ng-repeat="(key, value) in assets | filterBy : ['AssetType'] : 0 | groupBy : 'Grouping.Name' ">
<b>{{ key }}</b> - {{ numGroups(key) }}<br />
<div ng-repeat="asset in value ">
{{ asset.Name }}
</div>
</div>
But when I added a function to get the count of keys for this filtered group, I got something unexpected:
Other - 5
Image1.jpg
Facebook - 8
Image2.jpg
numGroups is defined like this:
$scope.numGroups = function (key) {
return Object.keys(key).length;
}
I was expecting the length of keys to be 2 (Other and Facebook) but instead it looks like it is iterating all the items of the array.
Is there any way to get the count of group keys after a filter has been applied?
There is a way!
Here's how the solution worked out:
$scope.numGroups = function (map) {
var count = 0;
angular.forEach(map, function () { count++; });
return count;
}
and the Html
<div class="group" ng-repeat="(key, value) in images = (assets | filterBy : ['AssetType'] : 0 | groupBy: 'Grouping.Name') ">
<div class="groupName" ng-hide="numGroups(images) == 1"><b>{{ key }}</b></div>
<div ng-repeat="asset in value">
{{ asset.Name }} - Brand {{ asset.Brand.Name }}
</div>
</div>
In your function 'numGroups' you are getting the length of the 'Grouping.Name' String, it could be fixed if you use this:
<div class="group" ng-repeat="(key, value) in grouped = (assets | groupBy : 'Grouping.Name') ">
<b>{{key}}</b> - {{numGroups(grouped)}} <br />
<div ng-repeat="asset in value">
{{ asset.Name}}
</div>
</div>
And a tricky way of your noumGroups function:
$scope.numGroups = function(map){
var count = 0;
angular.forEach(map, function(){
count++;
})
return count;
}

using part of a list in angularJS ng-repeat

I'm doing an angularJS data-binding as follows:
<div class="timeSlotWrapper">
<div class="timeSlotItem" ng-repeat="t in timeSlots" time-slot-obj="t" id ="{{t.id}}"
ng-click="timeSlotClick(cardId, $index)">{{ t.signalingTimeSlot}}</div>
</div>
the collection timeslots contain some 60 items, 30 of each belonging to one category. Lets say typeId is 0 for 30, and 1 for the other 30. I want to use ng-repeat for the first 30 only. Is it possible to do within ng-repeat or do I have to create the collection according to my need in code behind?
<div class="timeSlotWrapper">
<div class="timeSlotItem" ng-repeat="t in timeSlots | filter:{typeId:0}" time-slot-obj="t" id ="{{t.id}}"
ng-click="timeSlotClick(cardId, $index)">{{ t.signalingTimeSlot}}</div>
</div>
You can make use of angular filter. Example for same
myApp.filter('filterList', function () {
return function(id) {
if(id==1)
return id;
}
});
And in your html markup
<div class="timeSlotItem" ng-repeat="t in timeSlots | filterList:t.id" time-slot-obj="t" id ="{{t.id}}"
ng-click="timeSlotClick(cardId, $index)">{{ t.signalingTimeSlot}}</div>
UPDATE:
If 1 need not be hardcoded then a $scope object can be used in the filter:
myApp.filter('filterList', function () {
return function($scope) {
$scope.Objs.forEach(function(Obj){
if(id==$scope.Obj.id) {
return id;
}
});
}
});
and in html markup pass this object
<div class="timeSlotItem" ng-repeat="t in timeSlots | filterList:this" time-slot-obj="t" id ="{{t.id}}"
ng-click="timeSlotClick(cardId, $index)">{{ t.signalingTimeSlot}}</div>
Documentation on Angular Filters

Resources