Rearrange JSON multi-level array - angularjs

I receive a Json array from web service. This array contains others arrays.
How can I transform this structure to a one-level array to create a HTML table?
For instance, given this structure,
[
{
"uuid": "3f3f363d-322",
"name": "xxx",
"pay":[
{
"uuid": "123",
"number": "9791070",
},
{
"uuid": "124",
"number": "9791071",
}
]
}
]
... I want to change to this structure:
[
{
"uuid": "3f3f363d-322",
"name": "xxx",
"pay":
{
"uuid": "123",
"number": "9791070",
}
},
{
"uuid": "3f3f363d-322",
"name": "xxx",
"pay":
{
"uuid": "124",
"number": "9791071",
}
}
]
I tried to use ng-repeat and ng-if like this :
<tr ng-repeat="entry in entries >
<div ng-if="entry.pay.length>1">
<div ng-repeat=item in entry.pay">
<td>entry.uuid</td>
<td>pay.number</td>
</div>
</div>
Thanks

You can repeat <tbody> and within each <tbody> repeat <tr>.
Your html is invalid since <div> can't be child of <tr> or parent of <td>
<tbody ng-repeat="entry in entries" ng-if="entry.pay.length" >
<tr ng-repeat="item in entry.pay">
<td>entry.uuid</td>
<td>pay.number</td>
</tr>
</tbody>

except for some typos and missing braces your idea is correct, try:
<div ng-repeat="entry in entries >
<div ng-if="entry.pay.length>1">
<div ng-repeat="item in entry.pay">
<span>{{entry.uuid}}</span>
<span>{{item.number}}</span>
</div>
</div>
</div>
Furthermore its worth mentioning as said before that your html is invalid

Related

Targeting specific data items with a particular key with ng-repeat

I have a JSON object like the following:
{
"name": "cameraasd_main_autofocus",
"value": "Lasasd autofocus",
"displayName": "Autofocus"
},
{
"name": "screen_siasdze",
"value": "5.2\asd",
"displayName": "Sdascreen Size",
"group": "General"
},
{
"name": "camera_maindas_features",
"value": "Digital Zoom,das Auto Flash, Digital image stabilization"
"displayName": "Features"
},
In this data object I only want to target the element which have the group attribute with ng-repeat. And I have to further group out the elements with a particular group. For example from the whole object the elements with group value "General" should be separated from the rest of the elements.
You can create a scope variable to store the filtered items that have property "group" like below
var data = [{
"name": "cameraasd_main_autofocus",
"value": "Lasasd autofocus",
"displayName": "Autofocus"
},
{
"name": "screen_siasdze",
"value": "5.2asd",
"displayName": "Sdascreen Size",
"group": "General"
},
{
"name": "camera_maindas_features",
"value": "Digital Zoom,das Auto Flash, Digital image stabilization",
"displayName": "Features"
}];
$scope.filteredData = data.filter(function(x){ return x.hasOwnProperty("group")});
and then use ng-repeat in UI
<ul>
<li ng-repeat="item in filteredData">
{{item.name}} || {{item.value}}
</li>
</ul>
Here is a working sample : https://jsfiddle.net/Lt7aP/8267/
Edit : if you want to separate out the elements based on a particular group name then you can try the below code
$scope.filteredData = data.filter(function(x){ return x.hasOwnProperty("group") && x.group == "General"});
in this case only General groups will be displayed.
<div ng-repeat="x in records">
<div ng-if="x.group"> {{x.name}} </div>
</div>
try out if this works!! Good Luck!
Supposing your JSON contains an array (which is not show in your json but i assume it's there).
First, parse your JSON to a JsonObject, then get it as an array
JSONArray jsonArray = new JSONArray(jsonString);
Then you can do this in your html
<div ng-repeat="elem in jsonArray">
<a ng-if="elem.group">{{ elem.property }}</a>
</div>
Check this code.
<div>
<h3>With Group</h3>
<div ng-repeat="d in data">
<div ng-if="d.group">
{{d.name}}
</div>
</div>
</div>
<div>
<h3>Without Group</h3>
<div ng-repeat="d in data">
<div ng-if="!d.group">
{{d.name}}
</div>
</div>
</div>

How to add 2D array values to ng-repeat

I have a 2d array which has data something like this,
categoryinfo[0][0] = {"name": "apple", "category": { "name": "fruits","id": "09a8597d"}}
categoryinfo[0][1] = {"name": "orange", "category": { "name": "fruits","id": "09a8697d"}}
categoryinfo[1][0] = {"name": "fish", "category": { "name": "meat","id": "09a8447d"}}
I want to display these data according to the category, As you can see the [0]the index has all the fruit items and the [1]index has all the meat items.
I want to display these as,
Fruits
Apple
Orange
meat
fish
<table>
<thead>
<tr>
<th>{{categoryinfo[0][0].category.name}}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="formnames in categoryinfo">
<td>{{formnames[0].name}}</td>
</tr>
<tr ng-repeat="formnames in categoryinfo">
<td>{{formnames[1].name}}</td>
</tr>
</tbody>
</table>
to be more specific something like this above. But I cant figure out how to do this dynamically without hardcoding like this.
2D arrays are just arrays in an array, just loop over them layer by layer will do.
<table>
<thead ng-repeat-start="category in categoryinfo">
<tr>
<th>{{category[0].category.name}}</th>
</tr>
</thead>
<tbody ng-repeat-end>
<tr ng-repeat="item in category">
<td>{{item.name}}</td>
</tr>
</tbody>
</table>
You repeat them using $index.
The first iteration iterates over y(vertical) and then the one inside gives you x(horizontal) values.
Have a look at the code below.
var app = angular.module('repeatSamples', []);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
$scope.categoryinfo = [];
$scope.categoryinfo[0] = []
$scope.categoryinfo[0][0] = {
"name": "apple",
"category": {
"name": "fruits",
"id": "09a8597d"
}
}
$scope.categoryinfo[0][1] = {
"name": "orange",
"category": {
"name": "fruits",
"id": "09a8697d"
}
}
$scope.categoryinfo[1] = []
$scope.categoryinfo[1][0] = {
"name": "fish",
"category": {
"name": "meat",
"id": "09a8447d"
}
}
$scope.categoryinfo[1][1] = {
"name": "mutton",
"category": {
"name": "meat",
"id": "09a8447d"
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script><link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js" integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn" crossorigin="anonymous"></script>
<body ng-app="repeatSamples" ng-controller="MainCtrl">
<table class="table-bordered" ng-repeat="category in categoryinfo">
<thead>
<tr>
<th>{{category[$index].category.name}}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="formnames in categoryinfo[$index]">
<td>{{formnames.name}}</td>
</tr>
</tbody>
</table>
</body>
As Commented,
I guess this should do it, though not tried <div ng-repeat="c in category"><h3>{{c[0].category.name}} <p ng-repeat="list in c">{{list.name}}</h3>
Idea:
Since you have 2-D array, you will have to use 2 loops. One to iterate over parent list and other to loop over child list.
Also since you have already grouped items based on category, you can access first element for title.
If the data structure is not fixed and you can change it, you can look into creating a hashmap. You would still need 2 loops but that might make it easier to retrieve data.
function MainCtrl($scope) {
$scope.categoryInfo = {
fruits: [
{"name": "apple","id": "09a8597d"},
{"name": "orange", "id": "09a8697d"}
],
meat: [
{"name": "fish", "id": "09a8447d"}
]
}
};
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.21/angular.min.js"></script>
<body ng-app ng-controller="MainCtrl">
<div ng-repeat="(key, value) in categoryInfo">
<h3>{{key}} </h3>
<p ng-repeat="list in value">{{list.name}}</p>
</div>
</body>
Sample code:
function MainCtrl($scope) {
var categoryInfo = [[],[]]
categoryInfo[0][0] = {"name": "apple", "category": { "name": "fruits","id": "09a8597d"}}
categoryInfo[0][1] = {"name": "orange", "category": { "name": "fruits","id": "09a8697d"}}
categoryInfo[1][0] = {"name": "fish", "category": { "name": "meat","id": "09a8447d"}}
$scope.categoryInfo = categoryInfo;
};
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.21/angular.min.js"></script>
<body ng-app ng-controller="MainCtrl">
<div ng-repeat="c in categoryInfo">
<h3>{{c[0].category.name}} </h3>
<p ng-repeat="list in c">{{list.name}}</p>
</div>
</body>

unable to loop through an string array within angular ng-repeat

I have a Java object returned from a servlet which I convert into a JSON and fed back to angular as a scope variable to be displayed.
This Java object along with some string variables has a string array.
This is how the JSON looks: (the below JSON is stored on $scope.detail)
{"details":
{"0":{"Var1":"val1","Var2":"val2","Arr1":["0","0","2",null,null,null]},
{"1":{"Var1":"val1","Var2":"val2","Arr1":["0","0","2",null,null,null]}
}
I am able to successfully iterate over the items using ng-repeat except for "Arr1". A few responses on the website show that I should be able to iterate using another ng-repeat but the below doesn't work for me. Please suggest. Thank You.
<table ng-repeat="item in detail.details">
<tr>
<td>item.Var1</td>
<td>item.Var2</td>
<td>
<div ng-repeat="val in item.Arr1">
{{val}}
</div>
</td>
</tr>
</table>
The JSON you have provided is not valid JSON.
With the least modifications, I would suggest re-formatting it to look something like this:
{
"details": [
{
"Var1":"val1","Var2":"val2","Arr1":["0","0","2",null,null,null]
},
{
"Var1":"val1","Var2":"val2","Arr1":["0","0","2",null,null,null]
}
]
}
Although this is now valid JSON, I still think you should consider reformatting your JSON even more to easily consume it by the AngularJS app.
Here is a Plunker to illustrate a solution.
Check your JSON, it is not valid. The 2nd property of your details object is not structured well check for { and }, they are not placed correctly.
You can use https://jsonformatter.curiousconcept.com/ to restructure your JSON and check of errors
Below is the corrected JSON:
{
"details":{
"0":{
"Var1":"val1",
"Var2":"val2",
"Arr1":[
"0",
"0",
"2",
null,
null,
null
]
},
"1":{
"Var1":"val1",
"Var2":"val2",
"Arr1":[
"0",
"0",
"2",
null,
null,
null
]
}
}
}
Your HTML seams OK, just add track by $index and print your item.Var1 and item.Var2 using interpolate operator
<table ng-repeat="item in detail.details">
<tr>
<td>{{item.Var1}}</td>
<td>{{item.Var2}}</td>
<td>
<div ng-repeat="val in item.Arr1 track by $index">
{{val}}
</div>
</td>
</tr>
</table>
I hope this helps
Some observations as per your code :
Your JSON is not valid
It should be structured like this :
use ng-repeat="(key,val) in detail.details" instead of ng-repeat="item in detail.details" as detail.details is an object not an array.
DEMO
var myApp = angular.module('myApp',[]);
myApp.controller('MyCtrl', function($scope) {
$scope.detail = {
"details": {
"0": {
"Var1": "val1",
"Var2": "val2",
"Arr1": ["0", "0", "2", null, null, null]
},
"1": {
"Var1": "val1",
"Var2": "val2",
"Arr1": ["0", "0", "2", null, null, null]
}
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
<table ng-repeat="(key,val) in detail.details">
<tr>
<td>{{val.Var1}}</td>
<td>{{val.Var2}}</td>
<td>
<div ng-repeat="item in val.Arr1">
{{item}}
</div>
</td>
</tr>
</table>
</div>

Angularjs: how to replace , with line break<br> in angular filter

My doubt is simple. How to replace , with line break in angular filter. i also added the demo jsfFiddle
angular
.module('myApp', [])
.filter('nicelist', function() {
return function(input) {
if (input instanceof Array) {
return input.join(",");
}
return input;
}
})
.controller('ctrl', function($scope) {
$scope.todolists = [{
"id": "id_584",
"customer_id": 2,
"url": "url",
"bill_number": "123",
"location": "from_location"
}, {
"id": "id_122",
"customer_id": 3,
"url": "url",
"bill_number": "123",
"location": "from_location"
}, {
"id": "id_128",
"customer_id": 4,
"url": "url",
"bill_number": "123",
"location": "from_location"
}, {
"id": "id_805",
"customer_id": 5,
"url": "url",
"bill_number": "123",
"location": "from_location"
}, {
"id": "id_588",
"customer_id": 6,
"url": "url",
"bill_number": "123",
"location": "from_location"
}, {
"id": ["id_115"," id_114"],
"customer_id": 7,
"url": "url",
"bill_number": "123",
"location": "from_location"
}]
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myApp" ng-controller="ctrl">
<table class="table table-hover tr-table transactions" style="width: 100%;">
<thead>
<tr class="search-row pending-orders table-header-row-height tr-table-head">
<th>ID</th>
<th>Bill Number</th>
<th>Location</th>
<th>Url</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="todolist in todolists">
<td>{{todolist.id | nicelist }}</td>
<td>{{todolist.bill_number}}</td>
<td>{{todolist.location}}</td>
<td><a target="_blank" href="{{ 'http://' + todolist.url}}">Download Invoice : <i title="Download Invoice" style="padding-left:5px;cursor:pointer;color:black;" class="fa fa-download"></i></a> </td>
</tr>
</tbody>
</table>
</body>
demo
In the above link, there will be table. In ID column last row contain 2 values which is present in array inside the json. Now instead of comma(,) is there any possible way for line break.
Please share your knowledge.
you use ng-bind-html with injecting sanitize at module level .
html:
<tbody>
<tr ng-repeat="todolist in todolists">
<td ng-bind-html="todolist.id | nicelist"></td>
<td>{{todolist.bill_number}}</td>
<td>{{todolist.location}}</td>
<td><a target="_blank" href="{{ 'http://' + todolist.url}}">Download Invoice : <i title="Download Invoice" style="padding-left:5px;cursor:pointer;color:black;" class="fa fa-download"></i></a> </td>
</tr>
</tbody>
code:
angular.module('myApp', ['ngSanitize']) //Inject here
.filter('nicelist', function() {
return function(input) {
if (input instanceof Array) {
return input.join("<br>");
}
return input;
}
})
working sample up for grabs here.
ng-bind-html directive Documentation
PS: make sure you inject sanitize or you can use different techiques .

How to fill subcategories based on category selection in AngularJS

I have JSON data like this:
[
{
"id": "1",
"name": "abc",
"image": "abc.png",
"subcategories": [
{
"scid": "1",
"scname": "abc1"
},
{
"scid": "2",
"scname": "abc2"
},
{
"scid": "3",
"scname": "abc3"
}
]
},
{
"id": "2",
"name": "xyz",
"image": "xyz.png",
"subcategories": [
{
"scid": "4",
"scname": "xyz1"
},
{
"scid": "5",
"scname": "xyz2"
},
{
"scid": "6",
"scname": "xyz3"
}
]
}
]
and trying to fill categories and subcategories like this:
<tr>
<div class="form-group">
<TD>Category Name</TD>
<td>
<select class="form-control" ng-model="NewProduct.category" ng-options="category as category.name for category in Categories | orderBy:['name']" required></select>
</td>
</div>
</tr>
<tr>
<div class="form-group">
<TD>Sub Category Name</TD>
<td>
<select class="form-control" ng-model="NewProduct.subcategory" ng-options="subcategory as subcategory.name for subcategory in Categories.subcategories | orderBy:['scname'] | filter:{ 'id' : NewProduct.category.id }:true" required></select>
</td>
</div>
</tr>
Though categories are filling well, but no sub-categories are getting filled, after selecting category.
Can anyone help me what is wrong here?
In your second ng-options you say:
subcategory as subcategory.name for subcategory in Categories.subcategories
But Categories looks like it is probably an array, so won't have a .subcategories property. Instead I think you meant to use the category from your ngModel on the first select.
ng-model="NewProduct.category"
This would leave you with:
subcategory as subcategory.name for subcategory in NewProduct.category.subcategories

Resources