AngularJS ng-repeat duplicated error, when search is fired - angularjs

I have a listing using ng-repeat with a search for two available parameters (month and state).
If I make a search, I get a ng-repeat error found duplicates.
Can not understand why if in both cases the JSON data have the same structure (just the values will change).
I have these ng-repeats: item in data and nested inside : uniqueitem in item
I've tried to use track by $index but it loops for every single character, and for item.index or item.label1 but triggers the found duplicates erros again.
Here is my loop using ng-repeat.
<tbody ng-repeat="item in data">
<tr ng-repeat="uniqueitem in item">
<td>
{{uniqueitem.label1 | number}}
</td>
<td>
{{uniqueitem.label2 | number}}
</td>
My JSON has this structure :
[
{
"index": 0,
"label1": "Initials",
"label2": "2",
"label3": "18",
"label4": "12",
"label5": 150,
"label6": "30",
"label7": 60,
"label5A": "v",
"label7A": "r"
},
{
"index": 1,
"label1": "Others",
"label2": 5485,
"label3": 27289,
"label4": 37776,
"label5": 72.23,
"label6": 91949,
"label7": 29.67,
"label5A": "r",
"label7A": "r"
},
....
]

Just works !
Inside
$http.post(ApiEndpoint.url,$scope.formData).success(function(data) {
Instead of this line :
$scope.data = JSON.stringify(data);
I add these lines :
var acp = {};
acp.resultdata = [ data ];
$scope.data = acp.resultdata;
I will replicate in a Plunkr, can not say why JSON.stringify causes this behavior.

Related

How to display array with ng-repeat

I have an json array of the form":
{
"School1": [{"name": "john", "age":"28"},
{"name": "paul", "age":"27"}],
"School2": [{"name": "david", "age":"27"},
{"name": "sil", "age":"28"}]
}
How do I display in the table in this form using ng-repeat in Angular:
----------
Name | Age
----------
School1
----------
john | 28
----------
paul | 2
----------
School2
----------
david| 27
----------
sil| 28
----------
I will Apreciate help with this.
You can perform some operation on your data and can create another object with the modified structure so that it can be used with ng-repeat to display the table in the form you want.
You can understand this better with an example.
This is your data that you want to display in table view
$scope.testData = {
"School1": [{"name": "john", "age":"28"},
{"name": "paul", "age":"27"}],
"School2": [{"name": "david", "age":"27"},
{"name": "sil", "age":"28"}]
}
We perform an operation on "testData" to identify the keys in this JSON Object which are "School1" and "School2".Following line performs that operation.
$scope.keys = Object.keys($scope.testData);
$scope.keys will be an array of keys : ["School1",School2"];
Then you can iterate on the array of keys and create another object that can be used with ng-repeat in HTML code.
Following lines perform create that object(tableData):
$scope.tableData=[];
//Iterating on array of keys
$scope.keys.forEach(element => {
$scope.tableData.push({
column : element,
data : $scope.testData[element] //Getting your data from testData
});
});
Final Code Snippet that will go in the controller will be :
$scope.testData = {
"School1": [{"name": "john", "age":"28"},
{"name": "paul", "age":"27"}],
"School2": [{"name": "david", "age":"27"},
{"name": "sil", "age":"28"}]
}
$scope.keys = Object.keys($scope.testData);
$scope.tableData=[];
$scope.keys.forEach(element => {
$scope.tableData.push({
column : element,
data : $scope.testData[element]
});
});
And your HTML Code will go something like this:
<table>
<tr>
<th>Name |</th>
<th>Age</th>
</tr>
</table>
<table ng-repeat="table in tableData">
<tr>
<th>{{table.column}}</th>
</tr>
<tr ng-repeat="row in table.data">
<td>{{row.name}} | </td>
<td>{{row.age}}</td>
</tr>
</table>
You can definitely beautify the table view by writing your own css or by including any predefined stylesheets.
Hope that helps!!

Basic array looping in AngularJS

Can someone explain to me why this doesn't loop?
If I pre napIncident it gives null.
My code
<tr ng-repeat="napIncident in vm.NapIncidents">
<pre>{{vm.NapIncidents | json}}</pre>
<td>
{{napIncident.Incident}}
</td>
Pre output
[
{
"NapIncident": {
"Incident": "Zahlunsverbindungen ändern",
"IncidentID": "0002724285",
"NapID": "4214",
"NapStatus": "erfasst",
"Username": "silvat",
"NumberOfApprovers": "2",
"RecordDate": "12-12-2018",
"CheckerInformationList": [
{
"CheckerInformation": {
"Checker": "silvat",
"Date": "21-09-2018",
"TimeOfDay": "12:12:36",
"CheckerInfo": "Something",
"CheckerInfoText": "Something else"
}
}
],
"Alterations": [
{
"Alteration": {
"Field": "IBAN",
"OldValue": "DE12345",
"NewValue": "DE54321"
}
}
]
}
}
]
you have to access to your item . In your case is napIncident. Check your html part you will find ng repeat "NapIncident in vm.NapIncidents" .
To access to the details {{NapIncident.NapIncident.Incident}}
When using ng-repeat you map each item to a temporary variable, and when you have an array of named literals i.e array of NapIncident: {...} you must refer to NapIncident as a property :
<tr ng-repeat="item in vm.NapIncidents">
<td>
{{ item.NapIncident.Incident }}
</td>
<td>
{{ item.NapIncident.IncidentID }}
</td>
</tr>
and so on.

AngularJS orderby sorts number and dates treating them as string

I need to develop a table in angular js to show a third party data (and hence data cannot be changed).
Data to be shown is completely dynamic in that number or sequence of columns can change anytime.
The value to be displayed may be a number or a string or a date, which is governed by the third party data.
I need to sort table on clicking on any of the headers
I am aware of some techniques like using | number filter etc, but it does not seem to work in this dynamic environment
Hence I need to make my table as completely dynamic.
However I am facing issues in using order by as it sorts even numbers and dates treating them as string.
<table>
<td ng-repeat="key in keys(Header[0])" ng-click="maintainOrder(key)" >
<span>{{Header[0][key]}}</span>
</td>
<tr ng-repeat="singleRow in data | orderBy:orderByCriteria:reverseSort" >
<td ng-repeat="key in keys(data[0])" >
{{singleRow[key]}}
</td>
</tr>
</table>
$scope.maintainOrder = function(key)
{
$scope.orderByCriteria = key;
$scope.reverseSort = ! $scope.reverseSort;
};
$scope.keys = function(obj){
console.log((Object.keys(obj)));
return obj? Object.keys(obj) : [];
};
$scope.data= [
{
"quantity" : "85",
"type" : "mango",
"expiryDate" : "15/09/2015"
},
{
"quantity" : "9",
"type" : "orange",
"expiryDate" : "5/07/2015"
},
{
"quantity" : "66",
"type" : "apple",
"expiryDate" : "25/09/2015"
},
{
"quantity" : "95",
"type" : "mango",
"expiryDate" : "31/08/2015"
}
];
$scope.Header= [
{
"quantity" : "Qty ",
"type" : "Type",
"expiryDate" : "Expiry_Date"
}];
I have included a fiddle for the same:
fiddle link
You can create your own custom sort filter, and use the angular built-in functions angular.isNumber, angular.isDate, angular.isString
An example of a custom filter is here: http://jsfiddle.net/av1mLpqx/1/
In your custom filter, use a custom sort function like this:
array.sort(function (a, b) {
if (angular.isNumber(a) && angular.isNumber(b)) {
return a - b;
}
else if (angular.isDate(a) && angular.isDate(b)) {
return a.getTime() - b.getTime();
}
else if (angular.isString(a) && angular.isString(b)) {
return a.localeCompare(b);
}
else {
console.log("types unknown");
return 0;
}
}

How to get the next item in ng-repeat for an object?

I have an object as follows:
scope.items = {
"poor-John-1": {
"_id": "poor-John-1",
"name": "poor-John-1",
"sName": "room-poor-John-2"
},
"poor-John-2": {
"_id": "poor-John-2",
"name": "poor-John-2",
"sName": "room-poor-John-2"
}
}
I have rendered the object in the following way
<tr ng-repeat="item in items | orderObjectBy: '_id' track by item._id" ng-class="getStyle(item, next_item)"><td>{{item.sName}}</td></tr>
What I want to do is, pass, the current and next_item to the getStyle function, since its not an array, $index is not pointing the value. I have data in object.
Maybe you can do this with
$scope.keys = Object.keys($scope.items) // put keys on scope
// get next from keys
<tr ng-repeat="(key, item) in items track by item._id" ng-class="getStyle(item, items[keys[$index +1]])">
<td>{{key}}</td>
<td>{{item.name}}</td>
<td>next : {{items[keys[$index +1]]}}</td>
</tr>
Look this, tell me if it's what you want https://plnkr.co/edit/GCNmWb9Qv2mntqTnGsX1?p=preview

convert column value to a map value in ng-repeat

Nervous to ask this question.. HATE getting downvoted.. but it is what it is, I've searched and can't find the solution.
What I ended up doing is adding a loop that goes through my searchResults and reassigns the value for the column after the service returns inside the success block (PSEUDO CODE HERE, I can't copy and paste my actual code, there is an airgap):
var myNumberMap = {
1: "Number ONE!!",
2: "Number TWO!!",
3: "Number THREE!!!"
}
$scope.getSearchResults = function() {
$q.all({
resultSet : searchService.getSearchResults()
}).then(function(resultData) {
searchResults = resultData.resultSet;
for(var i = 0; i < searchResults.length; i++) {
searchResults[i].number = myNumberMap[searchResults[i].number];
}
}
}
I was really hoping there was some slick way I could just assign the data result value inside the grid config to be the value in the map?
Something like:
$scope.myCoolGridConfig = NgGridConfig.getConfig(
NgGridConfig.getDefaultConfig(), {
data: 'searchModel.searchResults.list',
columnDefs: [
field: 'number',
displayName: 'Number',
value: myNumberMap[searchModel.searchResults.list.number]
]
}
)
There are a few methods that you could take here:
Create a custom filter that you apply to your ng-repeat to transform the values based on your map.
Store your value map in your angular controller and bind the mapped value to the DOM.
// Controller
$scope.myMap = {
1 : "String One",
2 : "String Two",
3 : "String Three"
}
// something.html
<div ng-repeat='num in numList'>
{{myMap[num]}}
</div>
If I interpenetrated the question correctly your looking for something along these lines.
myMap = {
1 : "String One",
2 : "String Two",
3 : "String Three"
};
If the col number is 1 display String One instead of one in the table
Use myMap and look for the prop of col in it to pull the string value
<table>
<tr ng-repeat="col in tempCols">
<td>{{col}}</td>
<td>{{myMap[col]}}</td>
</tr>
</table>
If you need to do it towards an object that has no defining index such as the object below.
$scope.objectData = [{
name: "test1",
},
{
name: "test1",
},
{
name: "test1",
},
{
name: "test1",
},
{
name: "test1",
},
]
You can track it by $index + 1
<table>
<tr>
<td> Column Converted</td>
<td> Object name value</td>
<tr ng-repeat="col in objectData">
<td>{{myMap[$index + 1]}}</td>
<td>{{col.name}}</td>
</tr>
</table>
Heres a plunker for a better visual

Resources