I am trying to create pagination for my table that lists the objects returned from my DB as an object. My data structure will look something like:
$scope.myJSONObj = {
app1: {
id: 1,
appName: "appIntegrated1",
status: "Pending"
},
app2: {
id: 2,
appName: "appIntegrated2",
status: "Pending"
},
app3: {
id: 3,
appName: "appIntegrated3",
status: "Completed"
},
app4: {
id: 4,
appName: "appIntegrated4",
status: "Pending"
},
app5: {
id: 5,
appName: "appIntegrated5",
status: "Pending"
},
app6: {
id: 6,
appName: "appIntegrated6",
status: "Pending"
},
app7: {
id: 7,
appName: "appIntegrated7",
status: "Pending"
},
app8: {
id: 8,
appName: "appIntegrated8",
status: "Pending"
},
app9: {
id: 9,
appName: "appIntegrated9",
status: "Pending"
},
app10: {
id: 10,
appName: "appIntegrated10",
status: "Pending"
}
I am trying to split my structure in half, and display the first five results. I have a prev/next button, and when I click next, it should display the next 5 results (in this case the last 5). However, for everything to work, I need to be able to split my object, and so far every method I've researched involves arrays, and objects requiring some hack. I was wondering if I was missing something, or I have to create a solution to work with?
In pure JavaScript :
function getEntries(from, to) {
var entries = [];
for(var key in myJSONObj) {
// extract index after `app`
// var index = key.substring(3);
// Better way : extract index using regular expression, so it will match `something1`, `foo2`, `dummy3`
var index = parseInt(key.replace( /^\D+/g, ''));
if(index >= from && index <= to) {
entries.push(myJSONObj[key]);
}
}
return entries;
}
console.log(getEntries(0, 5));
Try _.chunk
https://lodash.com/docs/4.17.4#chunk
$scope.pages = _.chunk($scope.myJSONObj,5);
$scope.getPage = function( pageIndex ){
return $scope.pages[pageIndex];
}
It's untested - but I wrote a chunk method for you in vanilla JS since you can't use lodash.
function chunk(obj, chunkSize) {
var resultArray = [];
var resultArrayCurrentIndex = 0;
for (var key in obj) {
var item = obj[key];
if (resultArray[resultArrayCurrentIndex].length <= chunkSize) {
if (!resultArray[resultArrayCurrentIndex]) {
resultArray[resultArrayCurrentIndex] = [item];
} else {
resultArray[resultArrayCurrentIndex].push(item)
}
} else {
resultArrayCurrentIndex++
resultArray[resultArrayCurrentIndex] = [item];
}
}
return resultArray;
}
Then you can access it like this:
$scope.pages = chunk(yourObject, 5);
$scope.getPage = function(index){
return $scope.pages[index];
}
EDIT - changed it to accept an obj.
Used Object.keys, Array.prototype.slice and Array.prototype.reduce to solve your issue. Hope this helps
angular.module('app',[])
.controller('TestCtrl', function($scope){
$scope.myJSONObj = {"app1":{"id":1,"appName":"appIntegrated1","status":"Pending"},"app2":{"id":2,"appName":"appIntegrated2","status":"Pending"},"app3":{"id":3,"appName":"appIntegrated3","status":"Completed"},"app4":{"id":4,"appName":"appIntegrated4","status":"Pending"},"app5":{"id":5,"appName":"appIntegrated5","status":"Pending"},"app6":{"id":6,"appName":"appIntegrated6","status":"Pending"},"app7":{"id":7,"appName":"appIntegrated7","status":"Pending"},"app8":{"id":8,"appName":"appIntegrated8","status":"Pending"},"app9":{"id":9,"appName":"appIntegrated9","status":"Pending"},"app10":{"id":10,"appName":"appIntegrated10","status":"Pending"}};
$scope.currentPage = 0;
$scope.pageSize = 5;
$scope.totalPage = Math.ceil( Object.keys($scope.myJSONObj).length/$scope.pageSize);
//pageNumber starts from 0 here
$scope.goToPage = function(pageNumber) {
pageNumber = pageNumber>=0?pageNumber:0;
var from = pageNumber*$scope.pageSize;
var to = from + $scope.pageSize;
return Object.keys($scope.myJSONObj).slice(from,to).reduce(function(a,b){
a[b] = $scope.myJSONObj[b];
return a;
},{});
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="TestCtrl">
<button ng-disabled="currentPage===0" ng-click="currentPage = currentPage - 1">prev</button>
<button ng-disabled="currentPage===totalPage-1" ng-click="currentPage = currentPage + 1">next</button>
<b>Page: {{currentPage+1}}/{{totalPage}}</b>
<pre>{{goToPage(currentPage) | json}}</pre>
</div>
Related
I am new in angular and i want to re-group a JSON. Is it possible to do with angular.forEach() method?
[
{
"doc":{
"Title":"Main",
"name":"Ajith",
"Day":"03",
"count":3
}
},
{
"doc":{
"Title":"starters",
"name":"Saji",
"Day":"01",
"count":39
}
},
{
"doc":{
"Title":"desert",
"name":"Sajeeb",
"Day":"02",
"count":63
}
},
{
"doc":{
"Title":"Main",
"name":"Suith",
"Day":"03",
"count":3
}
},
{
"doc":{
"Title":"starters",
"name":"Manu",
"Day":"01",
"count":9
}
}
]
I want the output should be like following.
{
"order":[
{
"Day":"01",
"Title":"starters",
"items":[
{
"name":"Saji",
"count":39
},
{
"name":"Manu",
"count":9
}
]
},
{
"Day":"02",
"Title":"desert",
"items":[
{
"name":"Sajeeb",
"count":63
}
]
},
{
"Day":"03",
"Title":"Main",
"items":[
{
"name":"Ajith",
"count":3
},
{
"name":"Suith",
"count":3
}
]
}
]
}
To regroup with angular.forEach() method.
Please help. Thanks.
https://jsfiddle.net/9fwtm0a0/4/
var days = [];
arr.forEach(function(d) {
var day = parseInt(d.doc.Day);
var item = { name: d.doc.name, count: d.doc.count };
if (days[day])
days[day].items.push(item);
else
days[day] = { Day: '0' + day, Title: d.doc.Title, items: item]};
});
days.sort(function (x, y) {
return parseInt(x.Day) > parseInt(y.Day);
});
var eventsinOrder = { order: days };
You don't really need the Angular forEach but you can easily substitute it in:
var days = [];
angular.forEach(arr, function (val, key) {
var day = parseInt(val.doc.Day);
var item = { name: val.doc.name, count: val.doc.count };
if (days[day])
days[day].items.push(item);
else
days[day] = { Day: '0' + day, Title: val.doc.Title, items: [item]};
});
days.sort(function (x, y) {
return parseInt(x.Day) > parseInt(y.Day);
});
var eventsinOrder = { order: days };
Either way you go you will still need to make use of the sort function (or any equivalent) to perform the sorting while you're building this resultant object.
I have checked all stackoverflow posts related to ui-grid sorted rows without any success so I am opening one more question.
SHORT : Need a way to get sorted rows following current sorting criteria.
My problem is that I have an instance of UI Grid with pagination and I can not get the sorted data after it was added using a $mdDialog modal. It is shown at the right position in the tabel, but behind, in all objects it is stored the new element is on the last position.
I call the ui-grid instance using a service to keep all stuff in one place:
// Default service for init a ui-grid instance
app.serivce('testService', function(){
var defaultGridOptions = {
enableColumnMenus: false,
enablePaginationControls: true,
paginationPageSizes: [5],
multipleSorting: false,
treeRowHeaderAlwaysVisible: false,
paginationPageSize: 5,
enableHorizontalScrollbar: uiGridConstants.scrollbars.NEVER,
enableVerticalScrollbar: uiGridConstants.scrollbars.NEVER
};
// Each columns sort rule
// Position 0 from columnsOrder sorts position 0 from columnDefs and so on
var defaultColSort = [{
sort: { direction: uiGridConstants.ASC, priority: 0 }
}];
this.createGridOptions = function (gridData, columnDefs, gridOpts) {
gridOpts = typeof gridOpts !== 'undefined' ? gridOpts : {};
var gridOptions = angular.extend({}, defaultGridOptions, gridOpts);
for(var i = 0; i < defaultColSort.length; i++)
columnDefs[i] = angular.extend({}, defaultColSort[i], columnDefs[i]);
gridOptions.data = gridData;
gridOptions.columnDefs = columnDefs;
return gridOptions;
};
// The metod that should move to the desired page
this.jumpToGridItem = function(api, entry) {
var idx = -1;
var page = 0;
var sortedData = null;
// NEED A WAY TO GET SORTED DATA HERE
//idx = sortedData.indexOf(entry); -> checks the position of the new added item
if (idx == -1)
return false;
// Calculate the page where the element exists
page = Math.ceil(idx/api.grid.options.paginationPageSize);
// Jump to page
api.pagination.seek(page);
};
})
Here is my controller :
app.controller('testController', ['$scope', '$mdDialog', 'testService', function($scope, $mdDialog, testService){
var columnDefs = [
{
field: 'identifier',
name: 'Identifier'
}
];
var dummyData = [{ identifier: "Item" }, { identifier: 'Item 1' }, { identifier: "Item 2" }, { identifier: "Item 3" }];
var gridOptions = $scope.gridOptions = testService.createGridOptions(dummyData, columnDefs);
gridOptions.onRegisterApi = function (gridApi) {
$scope.gridApi = gridApi;
};
$scope.add = function () {
$mdDialog.show({
controller: function($mdDialog) {
var data = $scope.identifierVal;
$mdDialog.hide(data);
},
templateUrl: 'add.html',
parent: angular.element(document.body)
}).then(function (entry) {
// Data received when the modal is hidden
$scope.gridOptions.data.push(entry);
testService.jumpToGridItem($scope.gridApi, entry);
});
};
}]);
Right now I am appending the data with push(), this could be one reason, I think.
The method I have to update is jumpToGridItem, which actually should focus the page where the item was added.
Thank you
PS : Sorry for not posting a plnkr, I will do bit later if it is needed.
I finally found a way to achieve what I initially wanted. I ve found it a day after posting the question but I was busy enough to post the answer. The code below can be also found in a plnkr. It looks for a certain entry and goes to the page where it can be found.
I wanted this to focus a dynamically added entry in a ui-grid table from a dialog (modal form):
Controller :
var app = angular.module('stefanz', ['ui.grid', 'ui.grid.pagination']);
app.controller('MyCtrl', ['$scope', 'UIGridCustom', '$http', function($scope, UIGridCustom, $http){
// A part of data copied from ui-grid demos
var data = [{"name": "Ethel Price", "gender": "female", "company": "Enersol" },{"name": "Claudine Neal", "gender": "female", "company": "Sealoud" },{"name": "Beryl Rice", "gender": "female", "company": "Velity" },{"name": "Wilder Gonzales", "gender": "male", "company": "Geekko" },{"name": "Georgina Schultz", "gender": "female", "company": "Suretech" },{"name": "Carroll Buchanan", "gender": "male", "company": "Ecosys" },{"name": "Valarie Atkinson", "gender": "female", "company": "Hopeli" },{"name": "Schroeder Mathews", "gender": "male", "company": "Polarium" },{"name": "Lynda Mendoza", "gender": "female", "company": "Dogspa" },{"name": "Sarah Massey", "gender": "female", "company": "Bisba" },{"name": "Robles Boyle", "gender": "male", "company": "Comtract" },{"name": "Evans Hickman", "gender": "male", "company": "Parleynet" },{"name": "Dawson Barber", "gender": "male", "company": "Dymi" }];
var colDefs = [{
label: "name",
name: "name"
}, {
label: "gender",
name: "gender"
}, {
label: "company",
name: "company"
}];
// Call the service for init
var gridOptions = $scope.gridOptions = UIGridCustom.createGridOptions(data, colDefs);
gridOptions.onRegisterApi = function(api) {
$scope.gridApi = api;
}
$scope.getItemPage = function(name) {
UIGridCustom.jumpToGridItem($scope.gridApi, name);
}
}]);
app.service('UIGridCustom', ['uiGridConstants', 'utils', function(uiGridConstants, utils){
var defaultGridOptions = {
enableColumnMenus: false,
enableHorizontalScrollbar: uiGridConstants.scrollbars.NEVER,
enableVerticalScrollbar: uiGridConstants.scrollbars.NEVER,
enablePaginationControls: false,
paginationPageSize: 5,
multipleSorting: true
};
// Each columns sort rule
// Position 0 from columnsOrder sorts position 0 from columnDefs and so on
// Could be overwritten into columnDefs
// Docs : http://ui-grid.info/docs/#/api/ui.grid.class:GridOptions
var defaultColSort = [];
//1st column default sorting
defaultColSort[{
sort: { direction: uiGridConstants.ASC, priority: 0 }
}];
// For sorting 2nd column
// defaultColSort[1] = {
// sort: { direction: uiGridConstants.ASC, priority: 0 }
// };
this.createGridOptions = function (gridData, columnDefs, stefanzGridOpts) {
// Overwrite defaults with custom passed options for grid
var stefanzGridOpts = typeof stefanzGridOpts !== 'undefined' ? stefanzGridOpts : {};
var gridOptions = angular.extend({}, defaultGridOptions, stefanzGridOpts);
// Force sorting following the default/custom column sort
for(var i = 0; i < defaultColSort.length; i++)
columnDefs[i] = angular.extend({}, defaultColSort[i], columnDefs[i]);
// Grid init
gridOptions.data = gridData;
gridOptions.columnDefs = columnDefs;
return gridOptions;
};
this.jumpToGridItem = function(api, name) {
var idx = 0;
var page = 0;
var sorting = prepareCriteria(api.grid.getColumnSorting());
var data = dataObjectSort(prepareRows(api.grid.rows), sorting);
entry = getEntryByName(data, name);
idx = data.indexOf(entry) + 1;
if (!idx)
return false;
// Calculate the page where the element exists
page = Math.ceil(idx/api.grid.options.paginationPageSize);
alert(name + 'is found on page ' + page);
// Jump to page
api.pagination.seek(page);
};
// Takes the row's entity and put in a new array as a top-level item
// Userful for further data handling
var prepareRows = function(rows) {
if (rows.length == 0)
return false;
var preparedRows = [];
rows.forEach(function(row){
// Do not need to handle the rows that are not in current filter (hidden)
if (row.visible == false)
return true;
preparedRows.push(row.entity);
});
return preparedRows;
};
// We are comparing whole enter and as a parameter we are sending a name
var getEntryByName = function(data, searchedName) {
for(var i = 0; i < data.length; i++) {
if (data[i]['name'] == searchedName)
return data[i];
}
return false;
}
var dataObjectSort = function(data, criteria) {
return data.sort(utils.dynamicSortMultiple(criteria));
};
var prepareCriteria = function(colSorting) {
var sorting = [];
var fields = [];
// Take just needed fields
colSorting.forEach(function(column){
sorting.push({
field: column.field,
direction: column.sort.direction,
priority: column.sort.priority
})
});
// Sort criterias by priority - UI grid works like this
// Reason : http://ui-grid.info/docs/#/api/ui.grid.class:GridOptions.columnDef#properties_sort
sorting.sort(function(a, b){
if (a.priority < b.priority) return -1;
else if (a.priority > b.priority) return 1;
else return 0;
});
// Prepare fields for sorting
sorting.forEach(function(sort){
// Dymanic sort (above) needs "-" sign for descendent direction
if (sort.direction != uiGridConstants.ASC)
sort.field = '-' + sort.field;
fields.push(sort.field);
});
return fields;
};
}]);
// Keep utils methods into a separate service
// Here all sorting methods will appear
app.service('utils', function(){
function getJsonValue(obj, path) {
if (!path || path == '')
return obj;
path = path.split('.');
var len = path.length;
for (var i = 0; i < len - 1; i++) {
var prop = path[i].split(/\[([^\]]+)]/); // indication[4] => [indication, 4]; indication => [indication]
if (prop.length == 1) {
obj = obj[prop[0]];
} else {
obj = obj[prop[0]][prop[1]];
}
}
var prop = path[len - 1].split(/\[([^\]]+)]/); // indication[4] => [indication, 4]; indication => [indication]
if (prop.length == 1) {
return obj[prop[0]];
} else {
if (prop.length == 2) {
return obj[prop[0]][prop[1]];
} else {
if(prop.length ==3) {
return obj[prop[0]][prop[1]]; // this is a hack!
} else {
return obj[prop[0]][prop[1]][prop[3]]; // this is a hack!
}
}
}
};
//http://stackoverflow.com/questions/1129216/sort-array-of-objects-by-string-property-value-in-javascript/4760279#4760279
function dynamicSort(property) {
var sortOrder = 1;
if(property[0] === "-") {
sortOrder = -1;
property = property.substr(1);
}
return function (a,b) {
var aInsensitive = getJsonValue(a, property).toLowerCase();
var bInsensitive = getJsonValue(b, property).toLowerCase();
var result = (aInsensitive < bInsensitive) ? -1 : (aInsensitive > bInsensitive) ? 1 : 0;
return result * sortOrder;
}
};
function dynamicSortMultiple(props) {
return function (obj1, obj2) {
var i = 0, result = 0, numberOfProperties = props.length;
while(result === 0 && i < numberOfProperties) {
result = dynamicSort(props[i])(obj1, obj2);
i++;
}
return result;
}
};
return {
getJsonValue: function(obj, path) {
return getJsonValue(obj, path);
},
dynamicSort: function(property) {
return dynamicSort(property);
},
dynamicSortMultiple: function(props) {
return dynamicSortMultiple(props);
}
}
});
HTML
<!DOCTYPE html>
<html ng-app="stefanz">
<head>
<script data-require="angularjs_1_3_15#*" data-semver="1.3.15" src="https://code.angularjs.org/1.3.15/angular.min.js"></script>
<script data-require="angularjs_1_3_15#*" data-semver="1.3.15" src="https://code.angularjs.org/1.3.15/angular-animate.min.js"></script>
<script data-require="angularjs_1_3_15#*" data-semver="1.3.15" src="https://code.angularjs.org/1.3.15/angular-aria.min.js"></script>
<script data-require="jquery#*" data-semver="2.1.4" src="https://code.jquery.com/jquery-2.1.4.js"></script>
<link data-require="ui-grid#*" data-semver="3.0.7" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-grid/3.0.7/ui-grid.css" />
<script data-require="ui-grid#*" data-semver="3.0.7" src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-grid/3.0.7/ui-grid.js"></script>
<script data-require="bootstrap#~3.3.5" data-semver="3.3.6" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-controller="MyCtrl">
<div ui-grid="gridOptions" ui-grid-pagination class="grid"></div>
<div class="centerAlignedText">
<ul>
<li><a ng-click="getItemPage('Ethel Price')">Get Ethel Price</a></li>
<li><a ng-click="getItemPage('Schroeder Mathews')">Get Schroeder Mathews</a></li>
<li><a ng-click="getItemPage('Dawson Barber')">Get Dawson Barber</a></li>
<li><a ng-click="getItemPage('Sarah Massey')">Get Sarah Massey</a></li>
</ul>
</div>
<div class="centerAlignedText" ng-if="gridOptions.totalItems > 0">
<div class="paginationButtonsIcon boldText" style="width: 100px; display: inline-block;">
<md-button ng-if="gridApi.pagination.getPage() > 1" class="paginationButtons" ng-click="gridApi.pagination.previousPage()" style="width: 90px;">
<span class="notTransformedText boldText">Previous</span>
</md-button>
</div>
<div ng-repeat="n in gridApi.pagination.getTotalPages()" style="display: inline-block;">
<md-button ng-if="(gridApi.pagination.getTotalPages() < 11)
|| (gridApi.pagination.getPage() < 7 && n < 10)
|| (n > gridApi.pagination.getPage() - 7 && n < gridApi.pagination.getPage() + 4)
|| (gridApi.pagination.getPage() > gridApi.pagination.getTotalPages() - 5 && n > gridApi.pagination.getTotalPages() - 11)" class="paginationButtons md-mini md-icon-button md-primary" ng-click="gridApi.pagination.seek($index + 1)">
<span class="paginationButtonsIcon boldText" ng-if="gridApi.pagination.getPage() === $index + 1">
{{$index + 1}}
</span>
<span class="paginationButtonsIcon" ng-if="gridApi.pagination.getPage() !== $index + 1">
{{$index + 1}}
</span>
</md-button>
</div>
<div class="paginationButtonsIcon boldText" style="width: 100px; display: inline-block;">
<md-button ng-if="gridApi.pagination.getPage() < gridApi.pagination.getTotalPages()" class="paginationButtons md-icon-button md-primary" ng-click="gridApi.pagination.nextPage()" style="width: 90px;">
<span class="notTransformedText boldText">Next</span>
</md-button>
</div>
</div>
</body>
</html>
I'm trying to create a dynamic chart from userTemplate object.
I'm using this directive angular-flot and I want create the dataset and options of directive dynamically.
Its work but I have this error
Error: [$rootScope:infdig] http://errors.angularjs.org/1.2.21/$rootScope/infdig?p0=10&p1=%5B%5B%22fn%3…ection%5C%22%3A%7B%5C%22color%5C%22%3A%5C%22%2354728c%5C%22%7D%7D%22%5D%5D
at Error (native)
at http://mwm3-gui/asset/script/vendor/angular2.1/angular.min.js:6:450
at k.$get.k.$digest (http://mwm3-gui/asset/script/vendor/angular2.1/angular.min.js:110:66)
at k.$get.k.$apply (http://mwm3-gui/asset/script/vendor/angular2.1/angular.min.js:112:173)
at http://mwm3-gui/asset/script/vendor/angular2.1/angular.min.js:122:253
at e (http://mwm3-gui/asset/script/vendor/angular2.1/angular.min.js:37:440)
at http://mwm3-gui/asset/script/vendor/angular2.1/angular.min.js:41:120
HTML
<div ng-repeat="panel in row.panels" class="{{panel.columnClass}}" resizable id="{{panel.id}}" r-directions="['right']">
<flot dataset="getDataForChart(panel)" options="getOptionForChart(panel)" height="{{panel.graph.height}}"></flot>
</div>
CONTROLLER
$scope.userTemplate = [
{
blockId: 'blockUno',
title: 'Block title',
rows: [
{
rowId: 'rowUno',
title: 'Row Title 1',
panels: [
{
id: 'palel-report-1',
title: 'uno',
columnClass: 'col-md-4',
graph: {
height: 250,
type: "BAR",
countBy: "status"
}
},
{
id: 'palel-report-2',
title: 'due',
columnClass: 'col-md-4',
graph: {
height: 250,
type: "PIE",
countBy: "status"
}
},
{
id: 'palel-report-3',
title: 'tre',
columnClass: 'col-md-4',
graph: {
height: 250,
type: "BAR",
countBy: "status"
}
}
]
}
],
tables: []
}
];
$scope.getDataForChart = function(panel) {
var graphData = [];
var countBy = panel.graph.countBy;
var arr = $scope.reportingData;
for (var i = 0; i < arr.length; i++) {
var valueOfkey = arr[i][countBy];
graphData.push(valueOfkey);
}
var a = [], b = [], prev;
graphData.sort();
for (var i = 0; i < graphData.length; i++) {
if (graphData[i] !== prev) {
a.push(graphData[i]);
b.push(1);
} else {
b[b.length - 1]++;
}
prev = graphData[i];
}
var graphData = [];
for (var i = 0; i < a.length; i++) {
var singleO = {label: '' + a[i], data: [[i, b[i]]]};
graphData.push(singleO);
}
return graphData;
};
$scope.getOptionForChart = function(panel) {
var options = angular.copy($scope.defaultPlotOptions);
var typeGraph = panel.graph.type;
switch (typeGraph) {
case "BAR":
options.series.bars.show = true;
break;
case "LINE":
options.series.lines.show = true;
break;
case "PIE":
options.series.pie.show = true;
break;
case "POINT":
options.series.points.show = true;
break;
case "TABLE":
break;
}
return options;
};
The error you get is from an infinite digest loop.
In a couple of places you are calling functions that return new items each time. Here's an example from the docs linked from the error message you received that suggests this may cause this error:
One common mistake is binding to a function which generates a new
array every time it is called. For example:
<div ng-repeat="user in getUsers()">{{ user.name }}</div>
$scope.getUsers = function() { return [ { name: 'Hank' }, { name: 'Francisco' } ]; };
Since getUsers() returns a new array, Angular
determines that the model is different on each $digest cycle,
resulting in the error. The solution is to return the same array
object if the elements have not changed:
var users = [ { name: 'Hank' }, { name: 'Francisco' } ];
$scope.getUsers = function() { return users; };
In your code, you are doing the same binding to getDataForChart and getOptionForChart.
I am new at angularjs. So, it might be fool question.Anyway, please let me explain my problem. I have a table which is listed by ng-repeat and I'd like to change a column datas with another datas in another table column.
<tr data-ng-repeat=" list in listTypes">
<td>{{list.Comments}}</td>
<td>{{list.Modul}}</td>
<td>{{list.UserId}}</td>
<td data-ng-repeat="user in userNames">{{user.UserName}}</td>
I want to get UserName instead of UserId, but the problem that UserName is recorded in another table. Here is my angular for getting listTypes :
$scope.GetList = function () {
var onSuccess = function (response, status) {
//1
$scope.listTypes = response.Data;
var str = response.Data;
$scope.listTypes = eval('(' + str + ')');
for (var key in $scope.listTypes) {
$scope.listTypes[key].selected = "";
}
$scope.GetUserNames();
};
var data = null;
var request = $rest.GetList(data);
NGTools.CallNgServiceWithRequest(request, onSuccess, "GetList");
};
And trying to get usernames with this code:
$scope.userdatas= [];
$scope.userNames = [];
$scope.GetUserNames = function () {
var onSuccess = function (response, status) {
//1
$scope.userNames = response.Data;
};
$scope.userdatas= $scope.listTypes.UserId;
var data = { userdatas: JSON.stringify( $scope.userdatas) };
var request = $rest.GetUserNames(data);
NGTools.CallNgServiceWithRequest(request, onSuccess, "GetUserNames");
};
but it doesn't work. I couldn't figure out what's wrong with this code block. Please let me know if any tip is available. Thank you!
Assuming that you have to collections in your scope - one of which holds the id of the user, and the other holding the name, like so:
$scope.users = [
{ id: 1, name: 'John Doe' },
{ id: 2, name: 'Jane Doe' },
{ id: 3, name: 'Janice Doe' } ];
$scope.userInfo = [
{ userId: 1, gender: 'male' },
{ userId: 2, gender: 'female' },
{ userId: 3, gender: 'female' }];
Then what you could do is ng-repeat over the one with the userInfo and in your binding expression - use the id to get the name from the other collection:
<li ng-repeat="item in userInfo">
{{ item.gender }} {{ getNameFor(item.userId) }}</li>
Where the getNameFor is defined as:
$scope.getNameFor = function(id) {
var user = $scope.users.filter(function(item) { return item.id === id })[0];
console.log(user);
return user.name;
Which I checked in a fiddle here: http://jsfiddle.net/01kmoxw9/
I created a custom filter, but its giving me an error
I created a fiddle here:
Fiddle
I have this user data:
data: [{
profile: {
firstName: 'John',
lastName: 'OConner'
}
}, {
profile: {
firstName: 'Smith',
lastName: 'OConner'
}
}, {
profile: {
firstName: 'James',
lastName: 'Bond'
}
}]
And I need to filter by the nested obj - profile by this
data: [{
column: {
label: 'firstName',
}
}, {
column: {
label: 'lastName',
}
}]
I can filter but is giving me this error:
this is my filter:
myApp.filter('testFilter', ['$filter',
function($filter) {
return function(items, selectedFilter) {
var returnArray = items;
var filtered = [];
var process = {};
process.filtered = [];
process.loop = function(obj, key) {
var filtered = [];
this.obj = obj;
this.key = key;
// console.log('obj--> ', obj);
// console.log('key--> ', key);
filtered = filtered.concat($filter('filter')(items, process.superFilter));
if (filtered.length > 0) {
process.filtered = filtered;
}
};
process.superFilter = function(value) {
var returnMe;
var originalValue = value.profile[process.key];
if (typeof(value) === 'String') {
originalValue = originalValue.toLowerCase();
}
if (originalValue === process.obj) {
console.log('found');
returnMe = value;
return returnMe;
}
};
if (Object.getOwnPropertyNames(selectedFilter).length !== 0) {
angular.forEach(selectedFilter, function(obj) {
filtered = filtered.concat($filter('filter')(items, obj));
});
returnArray = filtered;
// console.log('selectedFilter ', selectedFilter);
}
return returnArray;
};
}
]);
Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys. How can I solve this issue?
You need to use track by as the error suggests. If you don't have a unique key to use you can use $index.
ng-repeat='talent in talents.data | testFilter:filterInput track by $index'
Here is a working example with your code: http://jsfiddle.net/hwT4P/