ng-repeat filter on json object - angularjs

I have a complex JSON structure as below:
My JSON object is like -
$scope.data = {
"Test 1": [
{
"paperName": "Physics Test",
"lkExamTypePk": 1,
"paperPK": "20",
"lkExamType": 2
}
],
"Test 2": [
{
"paperName": "Maths Test",
"lkExamTypePk": 2,
"paperPK": "23",
"lkExamType": 3
}
]
}
I am using this json to display in my html page and want to search key which is Test 1, Test 2, etc:
<input ng-model="filter.key" />
<table>
<tr ng-repeat="(key,val) in controllerName.data | filter:filter.key">
<td>
{{key}}
</td>
</tr>
</table>
But the problem is that filter works on array and on the values of JSON and I am getting error of not an array.
Error which I'm getting at the console
Error: [filter:notarray]

I think you problem is in how you refer your variabile. As I can see you are declaring your data array into $scope variabile with
$scope.data = { ... }
Then you try to access it referring to your controller with
controllerName.data
You can follow 2 different approaches, but you can't mix them.
1) $scope variabile
If you want to work into $scope, in your controller you must declare your variabile as follow:
$scope.data = { ... }
then into html you must refer to it like this (without controllerName):
<tr ng-repeat="(key,val) in data | filter:filter.key">
2) controller scope
If you want to work into controller's scope, in your controller you must declare your variabile as follow:
this.data = { ... }
then into html you can refer to it like this:
<tr ng-repeat="(key,val) in controllerName.data | filter:filter.key">
Hint
Generally a good practice, when you receive an error referring to a variable, is to print your variable's data into html to check that you are referring well to it, something like:
<pre>{{ data | json }}</pre>
Try with array instead of object
You can try using an array intead of a json object, as suggested by the error, something like this:
$scope.data = [
"Test 1": [{
"paperName": "Physics Test",
"lkExamTypePk": 1,
"paperPK": "20",
"lkExamType": 2
}],
"Test 2": [{
"paperName": "Maths Test",
"lkExamTypePk": 2,
"paperPK": "23",
"lkExamType": 3
}]
]

Related

Using ng-repeat print table in AngularJS with Filter

I want to use ng-repeat directive in AngularJS with customized filter to print a table.
Assume that I have data as following
[
{
"Key":{
"Name":"Paul",
"Age":"18"
},
"Info":{
"Gender":"M"
}
},
{
"Key":{
"Name":"John",
"Age":"19"
},
"Info":{
"Gender":"M"
}
},
{
"Key":{
"Name":"Jane",
"Age":"17"
},
"Info":{
"Gender":"F"
}
}
]
By using ng-repeat and filter, I hope that I could filtred by Name or other options.
So I tried:
<div>
<tr ng-repeat="x in data | myFilter: filterText">
<td>{{x.Key.Name}}</td>
<td>{{x.Key.Age}}</td>
</tr>
</div>
My script for customizing filter here:
myApp.filter("myFilter",function(){
return function(input, filterText){
if(input.Key.Name == filterText){
return input;
}
}
})
I keep receiving error from console that Name is undefined. I same have problem that accessing Javascript of Array of Object. I have set about JSON file input $scope.data.
filterText would be filter keywords for Name.
First of all, table tags are missing in your template. You can filter with nested property 'Name' without using custom filter like this:
<table>
<tr ng-repeat="x in data | filter: { Key: {Name: filterText} }">
<td>{{x.Key.Name}}</td>
<td>{{x.Key.Age}}</td>
</tr>
</table>
Check the working example : jsfiddle

angularjs filter multidimensional object json

I wnt to use ng-repeat to display a list filtered by an object value. Here is a plukr of my attempt https://plnkr.co/edit/vD4UfzM4Qg7c0WGTeY18?p=preview
The following returns all of my JSON names as expected.
<li ng-repeat="item in collection_data">{{navitem.name}}</li>
now i want to filter and only show the names of the items that have "foreign_lang": "es", like in this json snippet
{
"id": "ddb06ba2-6348-4d45-9e63-a6fa3632e5c2",
"created_at": "2015-10-12T18:34:15.668Z",
"updated_at": "2016-04-14T15:55:37.433Z",
"custom_attributes": {
"Display Name": "Activos en EspaƱol",
"foreign_lang": "es",
"display_boxes": "false"
},
},
so i made this filter function
$scope.filterByDisplay = function() {
$filter('filter')($scope.collection_data, ['foreign_lang', 'es']);
}
and called it like this.
<li ng-repeat="item in collection_data" | filter: filterByDisplay>{{navitem.name}}</li>
I did not get any console errors but i got nothing returned.
How do I properly filter through this collection to only return items with 'foreign_lang', 'es' as a value in the json? See the plunkr to see a working example https://plnkr.co/edit/vD4UfzM4Qg7c0WGTeY18?p=preview
Third attempt (since the question was revised). Use the filter function to check each object individually, and returning only those that pass the truth test.
$scope.filterByDisplay = function(value) {
return (value.content)
&& (value.content.custom_attributes)
&& (value.content.custom_attributes.foreign_lang === "es");
}
Updated Plunk - Using Filter Function

angular handsontable not working with regular scope variable

I have and angular scope variable called xd which i am trying to display in a table. When i use a regular table, it works fine:
<table class="table">
<tr ng-repeat="x in xd">
<th ng-bind="x.title"/>
</tr>
</table>
Now i am trying to use ngHandsonTable for the same purpose. As the documentation is still not proper, i tried something like this but somehow it is not showing anything. How do i use it to function properly?
<hot-table id="previewTable" columnHeaders="false" settings="htSettings" datarows="xd" >
</hot-table>
sample dataset of xd:
[
{
"title": "mytitle1"
}
{
"title": "mytitle2"
}
{
"title": "mytitle3"
}
]
Another output of xd:
[
{
"primary": "2",
"title": "mytitle1"
}
{
"primary": "3",
"title": "mytitle2"
}
{
"primary": "4",
"title": "mytitle3"
}
]
I would like to dynamically assign these column headers and values in the <hot-table>
After fiddling around with this, I came up with:
HTML table:
<div ng-app="demoApp" ng-controller="demoCtrl">
<hot-table
id="demoTable"
datarows="xd"
settings="{
colHeaders: xdColumns
}">
</hot-table>
</div>
Where the columns are the attribute names:
$scope.xdColumns = Object.keys($scope.xd[0]);
See this fiddle: https://jsfiddle.net/hysx1g10/4/
Since your data looks kind of confusing (every item has a title attribute), I'm not sure if that's what you're looking for. But as in a regular table you got one member (of the xd array) per row.

How do I filter angular results by id and other keys?

I want to filter results by id, or rating and various other keys, I'm using this data structure:
[
{
"id": "1"
"Description": "desc 1",
"Rating": "rating 1",
"MainImage": "image.jpg"
},
{
"id":"1"
"Description": "desc 2",
"Rating": "rating 2",
"MainImage": "image.jpg"
},
{
"id": "2"
"Description": "desc 3",
"Rating": "rating 3",
"MainImage": "image.jpg"
}
]
This data is returned from a promise and is assigned to $scope.results. In the template there is an ng-repeat to iterate over the results. This is working fine, my question is:
How do I filter the results by id so for example only the results with the id of 1 are displayed? I had this working but it wasn't the most efficient. I reassigned the filtered results back to $scope.results which did work but then the entire data structure had been replaced by the one containing the filtered results. That obviously wasn't going to work and I did a work around but I know this isn't the best way.
I need a custom filter that will be able to handle filtering using 3 different select lists so for example a rating select list, a productId and a productName.
How exactly would I write this function?
<div class="product" data-ng-repeat="product in products | filter:searchFilter"></div>
I ended up doing something that I found here and created a function in the backend. Something like:
$scope.searchFilter = function (item) {
return (item.id === $scope.results.id)
}
This code isn't exactly what I've used but that's the general idea. Seems to work :)
//This will filter the product list based on all 3 criteria
<div class="product" data-ng-repeat="product in products | filter:{rating:selectedRating, id:selectedId,productName:selectedProduct }"></div>
This is how I do it.
<input type="number" ng-modal="idFilter:selectedID">
<div ng-repeat="result in results | idFilter:selectedID | track by $index">
<something-repeated>
</div>
<script>
angular.module('whatever').filter('idFilter', function(){
return function(results, selectedID){
return results.filter(function(result){
return result.id == selectedID;
});
}
});
</script>

ng-repeat and nested array in json

i have some problems accessing some values stored in a json with the directive ng-repeat.
the json is formatted properly (checked it with a json checker) and it's called via $http service. unfortunately i can't change the format of json, retrieved through the wordpress-json-api plugin.
the json (with some cuts):
{
"status": "ok",
"count": 10,
"count_total": 24,
"pages": 3,
"posts": [
{
"id": 108,
"type": "sensor",
"slug": "ert",
"custom_fields": {
"sensor_id": [
"er"
],
"coords": [
"{\"address\":\"\",\"lat\":55.39979700000003,\"lng\":10.430533275390644,\"zoom\":12}"
]
}
}
//etc other posts following, json correct
Now i have a problem accessing the single values inside coords. i complained too about serializing data in db, but i'd like anyway to get lng and lat out of that array
<ul>
<li ng-repeat="post in sensor.posts">
<h4>name : {{post.id}}</h4> //ok
<h4>all custom fields : {{post.custom_fields}}</h4> //good-this-too
<h4>custom field lat : {{post.custom_fields.prova_coords[0]}}</h4> //works but can't go on
</li>
</ul>
the ouput of last line is:
custom field lat : {"address":"","lat":55.39979700000003,"lng":10.430533275390644,"zoom":12}
but now i'm stuck..can't retrieve single lat and long values
You need to use $scope.$eval(coordsString)
Here's a test: http://jsfiddle.net/mikeeconroy/Rnc7R/
var objString = "{\"address\":\"\",\"lat\":55.39979700000003,\"lng\":10.430533275390644,\"zoom\":12}";
$scope.coords = $scope.$eval(objString);
Then you can refer to coords.lat or coords.lng in your template like so:
<div ng-controller="myCoordsCtrl">
Lattitude: {{coords.lat}}<br>
Longitude: {{coords.lng}}
</div>
Since this is happening within an ngRepeat you may need to use an Angular filter to rectify the string on the fly
<li ng-repeat="post in sensor.posts | myRectifyCoordsFilter">
EDIT:
Don't use the filter like in the above example, using filters to modify $scope is not a good situation. You'll need to modify your $scope prior to using it in the ng-repeat
$http.get().success(function(data){
angular.forEach(data,function(val,key){
this.coords = $scope.$eval(val.coords[0]);
},data);
$scope.sensor = data;
});

Resources