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
Related
I know in my current version of Angular, ng-repeat auto sorts. My problem is that its sorting doesn't appear to be correct.
Taking an object with numbered keys:
{
"1": "value",
"2": "value",
"10": "value"
}
ng-repeat sorts it 1, 10, 2. I'm familiar with this sort of sorting and throwing a 0 on the front of number should fix it. However adding that 0 requires additional code and would need to be stripped out for display.
Likewise, converting to an array caused ng-repeat to loop through all of the empty values (3-9) and creates excess elements, as well as generating a duplicate error.
How can I make ng-repeat sort an object by keys as if they were integers?
I was not able to find a solution that didn't change your data structure, but here is an example of how it can be done by using keys to sort the object into an array. Here is the html:
<ul ng-controller="ExampleController">
<li ng-repeat="item in filtered">{{ item.value }}</li>
</ul>
And here is the code:
controller('ExampleController', ['$scope', function($scope) {
$scope.list = {
"1": "1 Value",
"10": "10 Value",
"5": "5 Value",
"2": "2 Value"
};
$scope.$watch('list', function (newVal) {
$scope.filtered = Object.keys(newVal).map(function (key) {
return { key: key, value: newVal[key] };
});
});
}]);
The output of this code looks like this:
1 Value
2 Value
5 Value
10 Value
Note that this creates an array of key/value pair objects which is easier to work with. Here is a plunker example of it working: http://plnkr.co/edit/Q0BYLeMzTZmd1k8VzTlQ?p=preview
I am using AngularJS template to show a JSON as a list/tree structure.
My JSON depth is unknown. In most of the cases my code works. There is just one case I have encountered so far that does not work.
My JSON sample:
[
{
"type":"image",
"bitmapname":{
"text":"Image_12.bmp"
},
"command":[
{
"type":"close",
"text":"1234"
},
{
"type":"place",
"text":"company"
},
{
"type":"key",
"key": "Tab"
},
{
"type":"keyboard",
"text":"welcome",
"command": [
{
"type":"open",
"text":"1234"
},
{
"type":"home",
"text":"company"
}
]
}
]
},
{
"type":"image",
"bitmapname":{
"text":"image_14.bmp"
},
"command":{
"type":"move",
"text":"right"
}
}
]
The output is below:
AngularJS code:
<script type="text/ng-template" id="xml.html">
<!-- XML is coming from controller as a JSON shown in my sample -->
<ul>
<li ng-repeat="item in XML">
[[ item["type"] ]]
<div ng-include=" 'xml.html' "
onload="XML = item.command">
</div>
</li>
</ul>
</script>
<div ng-include=" 'xml.html' ">
As you may noticed last list item is empty because that "command" is not an Array
I am trying to create a recursive function that will go through the JSON and create arrays on one element "command": [{...}] in places where I have "command": {...}
Can anyone suggest a solution that will convert the object to array of object wherever I have length-one object?
NOTE
I have no control over JSON being sent from Django backed. Python is using xmltodict extension to convert XML to Dictionary. Whenever XML tags have no children it does not create a list. It only creates a dictionary.
This isn't a very generic approach, but should work for your requirement:
function fixCommands(values) {
values.filter(function (v) {
return 'command' in v;
})
.forEach(function (v) {
if(v.command.constructor === Array) {
fixCommands(v.command);
} else {
v.command = [v.command];
}
});
}
jsfiddle example
You can check the first item that is it object or no if it was an object you can do a loop on it otherwise it's in other type that you have mentioned at top.for example
if(arr[i].command.length===undefined) -> so is string part
else -> is array part
I just started working with Angularjs and I'm facing the following problem:
I get this kind of object from an API request:
{
"recid": "1576",
"title": "19th Century UK Periodicals",
"description": "Bevat ruim 180 gescande tijdschriften die full text doorzoekbaar zijn",
"type": "tek",
"tags": "Engeland",
"primair": "b:bio",
"secundair": "h:eng,h:ges",
},
And I need to filter by selecting data that belongs to 'primair' OR 'secundair' field, how could I do that since chaining uses a sort of AND intead of Or.
regards in advance,
Eduardo
The easiest way would be to use a custom filter function. In your controller you would define it like this:
function YourController ($scope) {
$scope.filterFn = function (v) {
return (v.primair === 'somevalue') || (s.secundair === 'someothervalue');
};
}
In your template you can use it like this:
<li ng-repeat="item in yourlist | filter:filterFn">{{item.title}}</li>
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;
});
This is my first time playing with AngularJS, and actually, I'm following the getting-started tutorial. It came to my mind that I would tweak the tutorial scripts to my understandings, by just adding a little that was not in the tutorial.
Basically, the phone object used in the tutorial was:
{
"age": 1,
"id": "motorola-xoom",
"imageUrl": "img/phones/motorola-xoom.0.jpg",
"name": "MOTOROLA XOOM™",
"snippet": "The Next, Next Generation..."
}
What I was trying to do was to add an auto populated select box for order the list:
<select ng-model="orderProp">
<option ng-repeat="(key, value) in phones[0]" value="{{key}}">
{{labels[key]}}
</option>
</select>
and added a model labels to the controller:
$scope.labels = {
"name": "Phone name",
"snippet": "Description",
"age": "Newest",
};
It was working as expected, except that I only wanted to filter the 3 properties above, so I think it would be easy to add a custom predicated function for filtering like this:
$scope.isPhonePropFilterable = function (propName) {
console.log('it DOES NOT get here!!!');
return propName == 'name' || propName != 'snippet' || propName != 'age';
};
and added this to the ng-repeat
<option ng-repeat="(key, value) in phones[0] | filter:isPhonePropFilterable" value="{{key}}">
To my suprise, it was not as easy as I thought, my filter function was not called.
See it here: plunker
Did I do anything wrong?
edited: ng-repeat filter supports filtering array only, not object. The filter function returnes if array param is not an array...
Well, it was my fault. Ng-repeat filter supports array only, it did only mention array in the docs. And checking the filter function, it returned if array param is not an array....