Handling for loop in angular js - angularjs

I have a below JSON response, I need to populate my role information based on the role selected, I just moved roleinformation in roleInfo array , but the problem is I am unable to populate the key and value in the table accordingly.I am able to get the value , but couldnt populate in table. I couldn't move the key and its value to the table . I need move QA and Development with its sub key white box testing and Black box testing in my table. My for loop throw at error at end of termination.
JSON:
{
"json": {
"response": {
"servicetype": "1",
"functiontype": "10011",
"statuscode": "0",
"statusmessage": "Success",
"data": {
"unassignedroles": [
{"rolename":"1",
"roleinformation": {
"QA": [
{
"White Box Testing": 0
},
{
"Black Box Testing": 10
}
],
"Development": [
{
"White Box Testing": 0
},
{
"Black Box Testing": 10
}
]
}
},
{
` "rolename":"2"`,
"roleinformation": {
"1": [
{
"A": 0
}
]
}
}
JS:
var roleInfo = [];
UserService.getAssignRoles(json).then(function(response) {
if (response.json.response.statuscode == 0 && response.json.response.statusmessage == 'Success')
{
$scope.model.assignroles = [], assignrolesArray = [];
var unasresdata = response.json.response.data.unassignedroles;
var assresdata = response.json.response.data.assignedtoles;
assignrolesArray = unasresdata.concat(assresdata);
$scope.model.assignroles = assignrolesArray;
for( var i = 0; i < assignrolesArray.length ; i++){
if (($scope.model.rolename === assignrolesArray[i].rolename) && (assignrolesArray[i].rolename !== undefined )){
roleInfo = assignrolesArray[i].roleinformation;
for (i in roleInfo)
}
}
}
});
HTML:
<select class="form-control" name="role"
ng-model="model.rolename"
ng-change="getAssignRole(data,model.rolename)">
<option selected>Select Roles</option>
<option ng-repeat="role in model.assignroles track by $index"
value="{{role.rolename}}">{{role.rolename}}</option>
</select>
<div>
<table class="smalltable">
<thead>
<tr ng-repeat="i(key, value) in roleInfo">
<td>{{ key }}</td>
<td ng-repeat="details in value">
` <p ng-repeat"(subkey, subvalue) in details">{{ subkey }} : {{ subvalue }}</p>
</td>
</tr>
</thead>
</table>
</div>

Used angular.extend() to concate the object for roleInfo
$scope.roleInfo={};
for( var i = 0; i < assignrolesArray.length ; i++){
$scope.roleInfo = angular.extend($scope.roleInfo,assignrolesArray[i].roleinformation);
}
Refer to the below code and plunker link
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<div>
<table>
<thead>
<tr ng-repeat="(key,value) in roleInfo">
<td>{{ key }}</td>
<td ng-repeat="details in value">
<p ng-repeat="(subkey, subvalue) in details">
{{subkey}}:{{subvalue}}
</p>
</td>
</tr>
</thead>
</table>
</div>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
var response =
{
"json": {
"response": {
"servicetype": "1",
"functiontype": "10011",
"statuscode": "0",
"statusmessage": "Success",
"data": {
"unassignedroles": [{
"rolename": "1",
"roleinformation": {
"QA": [{
"White Box Testing": 0
}, {
"Black Box Testing": 10
}
],
"Development": [{
"White Box Testing": 0
}, {
"Black Box Testing": 10
}
]
}
}, {
"rolename": "2",
"roleinformation": {
"1": [{
"A": 0
}]
}
}]
}
}
}
};
var unasresdata = response.json.response.data.unassignedroles;
var assresdata = [{
"rolename": "1a",
"roleinformation": {
"QA": [{
"White Box Testing": 0
}, {
"Black Box Testing": 10
}
],
"Development": [{
"White Box Testing": 0
}, {
"Black Box Testing": 10
}
]
}
}, {
"rolename": "2a",
"roleinformation": {
"1": [{
"A": 0
}]
}
}];
var assignrolesArray = unasresdata.concat(assresdata);
console.log("This is assignedrolesArray : "+ assignrolesArray);
$scope.roleInfo={};
for( var i = 0; i < assignrolesArray.length ; i++){
$scope.roleInfo = angular.extend($scope.roleInfo,assignrolesArray[i].roleinformation);
}
});
</script>
</body>
</html>

Related

AngularJS loop variable not working as expected

The JSFiddle for this code is at http://jsfiddle.net/done_merson/x3r4o0aj/7/.
Here is the HTML:
<div ng-app="app" ng-controller="ctrl">
<div ng-repeat="category in model.categories"> <span> Category: {{ category.name }} </span>
<p ng-repeat="subCategory in getSubCategories(category.Id)">{{ subCategory.name }}
<p ng-repeat="subsubCategory in getSubSubCategories(subCategory.name)">{{ subsubCategory.amount }}
</p>
</div>
</div>
And here is the the JS code:
angular.module("app", [])
.controller('ctrl', ['$scope',
function ($scope) {
$scope.model = {
categories: [{
"Id": 1,
name: '1'
}, {
"Id": 2,
name: '2'
}],
subCategories: [{
"parentId": 1,
name: 'a1'
}, {
"parentId": 1,
name: 'a2'
},
{
"parentId": 2,
name: 'a3'
}],
subsubcategories:[
{
"name":'a1',
"amount": 43
},
{
"name":'a1',
"amount": 21
},
{
"name":"a2",
"amount": 25
},
{
"name":"a3",
"amount": 33
},
{
"name":"a3",
"amount": 17
}
]
}
$scope.getSubCategories = function(parentId){
var result = [];
for(var i = 0 ; i < $scope.model.subCategories.length ; i++){
if(parentId === $scope.model.subCategories[i].parentId){
result.push($scope.model.subCategories[i]);
}
}
console.log(parentId)
return result;
}
$scope.getSubSubCategories = function(name){
var subresult = [];
for(var i = 0 ; i < $scope.model.subsubcategories.length ; i++){
if(name === $scope.model.subsubcategories[i].name){
subresult.push($scope.model.subsubcategories[i]);
}
}
console.log(name)
return subresult;
}
}])
The first loop is working correctly (model.categories) but inner loop for the next loop is passing undefined for subCategory.name. Can I not pass the subCategory to the next loop? Or am I doing something wrong? What I am really trying to do is be able to create a report like you can with Access or ReportServer where you have grouping and summary of data. If anyone has any code like, I would love to see an example too.
Check now
angular.module("app", [])
.controller('ctrl', ['$scope',
function ($scope) {
$scope.model = {
categories: [{
"Id": 1,
name: '1'
}, {
"Id": 2,
name: '2'
}],
subCategories: [{
"parentId": 1,
name: 'a1'
}, {
"parentId": 1,
name: 'a2'
},
{
"parentId": 2,
name: 'a3'
}],
subsubcategories:[
{
"name":'a1',
"amount": 43
},
{
"name":'a1',
"amount": 21
},
{
"name":"a2",
"amount": 25
},
{
"name":"a3",
"amount": 33
},
{
"name":"a3",
"amount": 17
}
]
}
$scope.getSubCategories = function(parentId){
var result = [];
for(var i = 0 ; i < $scope.model.subCategories.length ; i++){
if(parentId === $scope.model.subCategories[i].parentId){
result.push($scope.model.subCategories[i]);
}
}
console.log(parentId)
return result;
}
$scope.getSubSubCategories = function(name){
var subresult = [];
for(var i = 0 ; i < $scope.model.subsubcategories.length ; i++){
if(name === $scope.model.subsubcategories[i].name){
subresult.push($scope.model.subsubcategories[i]);
}
}
console.log(name)
return subresult;
}
}])
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
<div ng-repeat="category in model.categories"> <span> Category: {{ category.name }} </span>
<p ng-repeat="subCategory in getSubCategories(category.Id)">{{ subCategory.name }}
<span ng-repeat="subsubCategory in getSubSubCategories(subCategory.name)">{{ subsubCategory.amount }} </span>
</p>
</div>
</div>
You have invalid html -- change inner p to span (also add </span>) and it will work.
Errors in html doesnt always result in such tricky things, but its better to always keep it valid.

AngularJS Filed nested array of objects with array of objects

I'm trying to filter a nested array of objects with my own objects, by idSubject. But I'm not getting the right result.
I have articles (which have subjects)
And a array of objects (which are the subjects I want to filter the articles with)
Data looks like this:
So I'm trying to filter the array of articles by its subjects.
I tried the following:
<div class="panel panel-default"
ng-repeat="searchArticle in searchArticles | filter: {subjects: filterSubjects} as articleSearchResult">
So filterSubjects is the second screenshot and SearchArticles is the first screenshot.
Without much luck.
Hope you can help, please tell me if things are still unclear.
This custom filter will help you.
Example : http://plnkr.co/edit/jMizCLxPH6DtDA5wL15Q?p=preview
HTML:
<body ng-app="myApp">
<div ng-controller="MainCtrl">
<h2>Select Subjects</h2>
<div ng-repeat="subject in subjects">
<label>
<input type="checkbox" ng-model="filterSubjects[subject.id]" ng-true-value="'{{subject.id}}'" ng-false-value="''">{{subject.name}}</label>
</div>
<h2>Filtered Articles</h2>
<div ng-repeat="searchArticle in searchArticles | subjectFilter:filterSubjects">{{searchArticle.name}}</div>
</div>
</body>
JS:
var app = angular.module('myApp', []);
app.controller('MainCtrl', function($scope) {
$scope.searchArticles = [{
"name": "Article1",
"sid": "1"
}, {
"name": "Article2",
"sid": "1"
}, {
"name": "Article3",
"sid": "2"
}];
$scope.subjects = [{
"name": "Subject1",
"id": "1"
}, {
"name": "Subject2",
"id": "2"
}];
$scope.filterSubjects = [];
});
app.filter('subjectFilter', function() {
return function(articles, filterSubjects) {
filtered = articles.filter(function(e){return filterSubjects.indexOf(e.sid) >= 0},filterSubjects);
return filtered;
}
});
if you want to filter based on object :
var app = angular.module('myApp', []);
app.controller('MainCtrl', function($scope) {
$scope.searchArticles = [{
"name": "Article1",
"sid": "1"
}, {
"name": "Article2",
"sid": "1"
}, {
"name": "Article3",
"sid": "2"
}];
$scope.subjects = [{
"name": "Subject1",
"id": "1"
}, {
"name": "Subject2",
"id": "2"
}];
$scope.filterSubjects = [{
"name": "Subject1",
"id": "1"
}, {
"name": "Subject1",
"id": "2"
}];
});
app.filter('subjectFilter', function() {
return function(articles, filterSubjects) {
var sFiltered = [];
for (var i = 0; i < filterSubjects.length; i++) {
sFiltered.push(filterSubjects[i].id);
}
var filtered = articles.filter(function(e) {
return sFiltered.indexOf(e.sid) >= 0;
}, sFiltered);
return filtered;
}
});

AngularJS - How do I filter an array of 'deep' objects given an array of values to filter by?

I am trying to filter my data which I am getting from a HTTP GET endpoint by an array of values
filters = ['Full Time', 'LinkedIn', ...]
The general structure of the response I am getting back is an array of objects where each object can look like this:
{
"preferences": {
"jobType": {
"type": "Full Time"
}
},
"profile": {
"additionalinfo": {
"organization": [
{
"name": "Google"
},
{
"name": "LinkedIn"
}
],
"university": [
{
"name": "UC Berkeley",
"degrees": [ {"name": "Computer Engineering"}]
}
}
}
}
So if I filter by ["Google", "Full Time"], the above object should be included.
Is there a built in filter to handle this?
I am having trouble writing the custom filter to handle such a heavily nested object.
Any ideas on how to implement this?
You can use built in filter like this jsfiddle
var myApp = angular.module("myApp", []);
myApp.controller("myCtrl", function($scope) {
$scope.data = [{
"preferences": {
"jobType": {
"type": "Full Time"
}
},
"profile": {
"additionalinfo": {
"organization": [{
"name": "Google"
}, {
"name": "LinkedIn"
}],
"university": [{
"name": "UC Berkeley",
"degrees": [{
"name": "Computer Engineering"
}]
}]
}
}
}, {
"preferences": {
"jobType": {
"type": "Remote"
}
},
"profile": {
"additionalinfo": {
"organization": [{
"name": "Yandex"
}, {
"name": "LinkedIn"
}],
"university": [{
"name": "UC Berkeley",
"degrees": [{
"name": "Computer Engineering"
}]
}]
}
}
}];
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.min.js"></script>
<body ng-app="myApp" ng-controller="myCtrl">
<h3>Jobs</h3>
<input ng-model="filterModelJobType" placeholder="filter jobType">
<input ng-model="filterModelJob" placeholder="filter job">
<table class="table table-striped table-bordered">
<tbody>
<tr ng-repeat="x in data|filter:{profile: {additionalinfo:{organization:{name:filterModelJob}}},preferences: {jobType:{type:filterModelJobType}}}">
<td>{{ $index + 1 | number }}</td>
<td class="text-center">{{ x.preferences.jobType.type }}</td>
<td class="text-left">
<div ng-repeat="org in x.profile.additionalinfo.organization">
<hr> {{org.name}}
</div>
</td>
</tr>
</tbody>
</table>
</body>
In the latest version of AngularJS
If there is nested object then
var foo = $filter('filter')($scope.welcome, {
additionalinfo: { name: 'google' }
});
Reference: GitHub issue

How to filter set of items from list of items - AngularJS

I have two scope variables in angularJS. One storing "all the subcategories" and other storing "categories and their respective subcategories".
$scope.Categories = [
{
"subcategories": [
{
"scname": "Sugar",
"scid": "5"
},
{
"scname": "Salt",
"scid": "6"
},
{
"scname": "Jaggery",
"scid": "7"
}
],
"name": "Salt and Sugar",
"id": "1",
"image": "/images/salt_sugar.png"
},
{
"subcategories": [
{
"scname": "Tea",
"scid": "8"
},
{
"scname": "Coffee",
"scid": "9"
},
{
"scname": "Tea Bags",
"scid": "162"
}
],
"name": "Tea and Coffee",
"id": "2",
"image": "/images/tea_and_coffee.png"
}
]
$scope.subcategories = [
{
"name": "Sugar",
"id": "5"
},
{
"name": "Salt",
"id": "6"
},
{
"name": "Jaggery",
"id": "7"
},
{
"name": "Tea",
"id": "8"
},
{
"name": "Coffee",
"id": "9"
},
{
"name": "Tea Bags",
"id": "162"
}
]
On selecting a category i want to display mapped and unmapped subcategories with that particular category. First one is very easy. How to filter second one? for example -
on selecting "Tea and Coffee" unmapped categories should be - Sugar, salt, Jaggery
on selecting "Salt and Sugar" unmapped categories should be - Tea, Coffee, Tea Bags
This is how I am listing mapped categories:
<TR align="center">
<TD>
<select ng-options="c as c.name for c in Categories|orderBy:'name' " ng-model="selectedCategory" size="10"> </select>
</TD>
<TD>
<select ng-options="sc as sc.scname for sc in selectedCategory.subcategories|orderBy:'scname' " ng-model="SelectedMappedSubCategory" size="10"> </select>
</TD>
<TD>
<select ng-options="sc as sc.name for sc in SubCategories | orderBy:'name' | ???????" ng-model="SelectedUnMappedSubCategory" size="10"> </select>
</TD>
</tr>
What logic should I use in-place if ?????????
If I understood correctly, why not just filter it?
| filter: {scname: SelectedUnMappedSubCategory.scname}
EDIT:
I can see that you edited the code you originally posted. I think you can achieve what you are trying to do, by this:
| filter: {id: SelectedUnMappedSubCategory.scid}
Create a customized filter:
sampleApp.filter('filterSubcategories', function() {
return function(input, filterkey) {
var filtered = [];
if (filterkey) {
for (var i = 0; i < input.length; ++i) {
var item = input[i];
var found = false;
for (var j = 0; j < filterkey.length; ++j) {
if (item.id == filterkey[j].scid) {
found = true;
break;
}
}
if (!found){
filtered.push(item);
}
}
}
return filtered;
};
});
and use this like:
<TD>
<select ng-options="sc as sc.name for sc in SubCategories | filterSubcategories:selectedCategory.subcategories | orderBy:'name'" ng-model="SelectedUnMappedSubCategory" size="10"> </select>
</TD>

Angular JS Order By Filter not working for dynamic predicates

I am creating a Grid Control in Angular JS. ( I don't want to use ng-grid, smart table, etc for some reason)
Plunkr URL : http://plnkr.co/edit/arkCZcfXTIsW7sFCxisn?p=preview
On top of the table generated, i have populated fields in the combobox so that user is allowed to search on specific columns
or as free search.
As I see From here :
https://docs.angularjs.org/api/ng/filter/filter
For free search, I have used the syntax as {$:Value} and for column based search, {ColName:Value} syntax
However, I am unable to get it to work when I bind the column names to combobox.
I do get static search to work Eg if I write {'Code':"1"}, this works. but if I take "Code" from a combobox, it doesnt work.
Need help on setting dynamic filter.
This one also does not seem to help.
angular filter with dynamic list of attributes to search
This is the HTML
<div ng-controller="MyGrid">
Search in Column
<select ng-model="FilterByColumn" >
<option value="$">All</option>
<option ng-repeat="hdr in headers | orderBy : hdr.displayOrder" ng-show="hdr.isVisible" value="{{hdr.name}}" >
{{hdr.caption}}
</option>
</select>
Value : <input type="text" ng-model="searchKeyword" />
<br />
Remove Sort
<table>
<thead>
<tr>
<th ng-repeat="hdr in headers | orderBy : hdr.displayOrder" ng-show="hdr.isVisible">
{{hdr.caption}}
</th>
</tr>
</thead>
<tbody>
<%--<tr ng-repeat="dataVal in data | filter: {FilterByColumn : searchKeyword} | orderBy:predicate:reverse "> **Does not work--%>**
<%--<tr ng-repeat="dataVal in data | filter: {$ : searchKeyword} | orderBy:predicate:reverse "> **This works--%>**
<tr ng-repeat="dataVal in data | filter: GetFilter (FilterByColumn, searchKeyword) | orderBy:predicate:reverse "> **<!-- Does not work -->**
<td ng-repeat="hdr in headers | orderBy : hdr.displayOrder" ng-show="hdr.isVisible">
{{dataVal[hdr.name]}}
</td>
</tr>
</tbody>
</table>
<pre>Sorting predicate = {{predicate}}; reverse = {{reverse}} ; SearchBy = {{FilterByColumn}} ; Search Key : {{searchKeyword}} </pre>
</div>
This is the JS :
'use strict';
var MyApp = angular.module('MyApp', []);
MyApp.controller('MyGrid', function ($scope) {
$scope.predicate = 'Code';
$scope.reverse = false;
$scope.FilterByColumn = '$';
$scope.headers = [
{
"name": "Code",
"caption": "Code",
"isVisible": true,
"displayOrder": 12
},
{
"name": "DispName",
"caption": "My Name",
"isVisible": true,
"displayOrder": 1
},
{
"name": "Locked",
"caption": "Islocked",
"isVisible": true,
"displayOrder": 2
}
];
$scope.data =
[{
"Code": "1",
"DispName": "abdul",
"Locked": "0"
},
{
"Code": "2",
"DispName": "Hemant",
"Locked": "0"
},
{
"Code": "3",
"DispName": "Rahul",
"Locked": "0"
},
{
"Code": "4",
"DispName": "Sandy",
"Locked": "0"
},
{
"Code": "5 ",
"DispName": "Nihal",
"Locked": "0"
},
{
"Code": "6",
"DispName": "Sachin",
"Locked": "0"
},
{
"Code": "7",
"DispName": "abdul f",
"Locked": "0"
},
{
"Code": "8",
"DispName": "abdul g",
"Locked": "0"
},
{
"Code": "9",
"DispName": "abdul h ",
"Locked": "0"
},
{
"Code": "10",
"DispName": "abdul i",
"Locked": "0"
}
];
$scope.getValue = function (obj, PropName) {
return obj[PropName];
};
$scope.SetSort = function (objName) {
//alert(objName);
$scope.predicate = objName;
$scope.reverse = !$scope.reverse;
};
$scope.GetFilter = function (srchCol, Srchval) {
//alert(srchCol);
//alert(Srchval);
if (srchCol == "") {
return { $: Srchval };
}
else {
return { srchCol: Srchval };
}
};
});
That is because when you write { srchCol: Srchval } - srcCol is the property name and is not substituted with the value in variable srcCol, try this syntax instead:
$scope.GetFilter = function (srchCol, Srchval) {
if (srchCol == "") {
return { $: Srchval };
}
else {
filter = {};
filter[srchCol] = Srchval;
return filter;
}
};

Resources