ng-repeat is not working for the json value - angularjs

I have a code like this:
<tr ng-repeat="tagJson in tagList">
<div ng-repeat="(key, value) in tagJson">
<td width="48%" ng-class-odd="'evn'" ng-class-even="'odd'">
{{key}}
</td>
<td width="48%" ng-class-odd="'evn'" ng-class-even="'odd'">
{{value}}
</td>
</div>
</tr>
where tagList is :
[{a:1},{a:1}]
But the key and value are empty! Not sure why thats the case. If i try to print tagJson in the html like:
{{tagJson}}
it does print:
{a:1}
{a:1}
but key and value doesnt work!
Where I'm making the mistakes?
See here:
http://jsfiddle.net/Vwsej/126/

The actual reason why you don't see anything is, as akonsu posted, because you're producing invalid html.
To keep the values in seperate table cells, you can use ng-repeat-start/end, e.g.:
var MainCtrl = function () {
this.tagList = [{a:1}, {b:2}];
};
angular
.module('app', [])
.controller('Main', MainCtrl)
;
table {
border-collapse: collapse;
}
td {
border: 1px solid #ccc;
padding: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-rc.5/angular.min.js"></script>
<div data-ng-app="app" data-ng-controller="Main as main">
<table>
<tr ng-repeat="tagJson in main.tagList">
<td ng-repeat-start="(key, value) in tagJson" width="48%" ng-class-odd="'evn'" ng-class-even="'odd'">
{{key}}
</td>
<td ng-repeat-end width="48%" ng-class-odd="'evn'" ng-class-even="'odd'">
{{value}}
</td>
</tr>
</table>
</div>

You do not see anything because this is invalid markup for the table. You have div elements inside.
maybe this?
<div ng-controller="MyCtrl">
<table>
<tr ng-repeat="tagJson in tagList">
<td ng-repeat="(key, value) in tagJson">
{{key}}={{value}}
</td>
</tr>
</table>
</div>
but to emit the markup that you wanted, I think you need a custom directive for that.

Related

angular js table odd column data issue

I am new to angular JS and working on table to have odd/even background colour change however I am facing some challenges.
Here is my code
<!DOCTYPE html>
<html>
<style>
table, td {
border: 1px solid grey;
border-collapse: collapse;
padding: 5px;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="customersCtrl">
<table>
<tr> <td style="background-color:green">Name</td> <td style="background-color:green">Country</td></tr>
<tr ng-repeat="x in names">
<td ng-if="$odd" style="background-color:#f1f1f1">
{{ x.Name }}</td>
<td ng-if="$even">
{{ x.Name }}</td>
<td ng-if="$odd" style="background-color:#f1f1f1">
{{ x.Country }}</td>
</tr>
</table>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('customersCtrl', function($scope, $http) {
$http.get("http://localhost:8080/getCustomer")
.then(function (response) {$scope.names = response.data.records;});
});
</script>
</body>
</html>
Output I am getting is not desirable, the odd country data is coming blank.
Use below code, I think for the column country odd condition is missing
<table>
<tr> <td style="background-color:green">Name</td> <td style="background-color:green"> Country</td></tr>
<tr ng-repeat="x in names">
<td ng-if="$odd" style="background-color:#f1f1f1">
{{ x.Name }}</td>
<td ng-if="$even">
{{ x.Name }}</td>
<td ng-if="$odd" style="background-color:#f1f1f1">
{{ x.Country }}</td>
<td ng-if="$even">
{{ x.Country }}</td>
</tr>
</table>
You can do it with CSS much more simple and clean code.
table tr:nth-child(odd) td{
//your style
}
table tr:nth-child(even) td{
}
You can also define the basic background color and then just use odd/even.
You can use CSS for background color change.
<style>
table, td {
border: 1px solid grey;
border-collapse: collapse;
padding: 5px;
}
tr:nth-child(odd) { background-color: #f1f1f1; }
</style>
The reason why your data is not coming properly is that you have used ng-if="$odd" to apply styles for odd columns.
So change your HTML to the following way and add background color from CSS.
<table>
<tr> <td style="background-color:green">Name</td> <td style="background-color:green">Country</td></tr>
<tr ng-repeat="x in names">
<td>
{{ x.Name }}</td>
<td>
{{ x.Name }}</td>
<td>
{{ x.Country }}</td>
</tr>
</table>

AngularJS - no two way binding for key-value object

Just for note, I know nothing about angularJS, I worked with knockoutJS before and when it comes to angular I am just making assumptions.
I have code like this:
angular.module("umbraco").controller("recallCtrl",
function ($scope, $routeParams) {
$scope.dcList = {
key: "value",
abc: "aaaa",
prop: "tadaa!"
}
});
and markup as follows:
<div ng-controller="recallCtrl">
<table class="table table-sm">
<thead>
<tr>
<td></td>
<th>Key</th>
<th>Value</th>
</tr>
</thead>
<tr ng-repeat="(key, value) in dcList">
<td>
</td>
<td>
<input ng-model="key" />
</td>
<td>
<input ng-model="value"/>
</td>
</tr>
</table>
<pre>{{dcList | json}}</pre>
</div>
So shouldn't output of dcList in the end of html change it's values when I edit corresponding inputs which as I assume are bound to object?
If I am doing something wrong, please advise. I want to create object and be able to change its keys and values.
The reason your current code isn't working is because the "key" and "value" variables are scoped within the ng-repeat, and no longer refer directly to the original object.
Keeping the "values" attached is easy, just use dcList[key] instead of value. Adding new keys takes a bit more work; here I've attached an ng-blur to each "key" field which will init a new key when the field blurs. (ng-change would create a new field on every keystroke, which isn't what you want.) Note that when you start typing a new key, its value appears to disappear -- this is because the dcList[key] refers to the new key name immediately. This would be somewhat confusing in a real UI, of course; you'd probably want to code different behavior into the createNewKey function (such copying the old value into the new key, or deleting the original key).
function recallCtrl($scope) {
$scope.dcList = {
key: "value",
abc: "aaaa",
prop: "tadaa!"
}
$scope.createNewKey = function(k) {
$scope.dcList[k]="";
}
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app>
<div ng-controller="recallCtrl">
<table class="table table-sm">
<thead>
<tr>
<th>Key</th>
<th>Value</th>
</tr>
</thead>
<tr ng-repeat="(key, value) in dcList">
<td>
<input ng-model="key" ng-blur="createNewKey(key)"/>
</td>
<td>
<input ng-model="dcList[key]"/>
</td>
</tr>
</table>
<pre>{{dcList | json}}</pre>
</div>
please test this code, change in the value corresponding to the key,
angular.module('app', [])
.controller('Controller', function($scope) {
$scope.dcList = {
key: "value",
abc: "aaaa",
prop: "tadaa!"
}
})
<!DOCTYPE html>
<html>
<head>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0/angular.min.js"></script>
</head>
<body ng-app="app">
<div ng-controller="Controller">
<table class="table table-sm">
<thead>
<tr>
<td></td>
<th>Key</th>
<th>Value</th>
</tr>
</thead>
<tr ng-repeat="(key, value) in dcList">
<td>
</td>
<td>
<input ng-model="key" disabled/>
</td>
<td>
<input ng-model="dcList[key]" />
</td>
</tr>
</table>
<pre>{{dcList | json}}</pre>
</div>
</body>
</html>
Here is the plunker

ng-if inside ng-repeat won't work

I have this piece of code on my HTML that I fill with Angular:
<table id="myTable">
<tr>
<th>Id</th>
<th>desc</th>
<th>prod kg</th>
<th>index</th>
</tr>
<tr ng-repeat="x in maq" ng-if="{{ x.index }}=='0'" id="{{ x.index }}">
<td style="border: 1px solid black;">{{ x.codigo }}</td>
<td style="border: 1px solid black;">{{ x.desc }}</td>
<td style="border: 1px solid black;">{{ x.prod_24_h_kg }}</td>
<td style="border: 1px solid black;">{{ x.index }}</td>
</tr>
</table>
No problem here so far. However I want to make and ng-if for each row as you can see, and let's say:
{{ x.index }}=='0'
I don't want that row to show up. I have tried many combinations of the " " and ' ' with no succes. Does anyone see the solution?
No need to use interpolation {{}} directive inside ng-if directive, It directly takes an expression which will evaluate against current scope.
ng-if="x.index ==0"
Rather another option to achieve same thing would be use filter.
ng-repeat="x in maq | filter: {index: 0} as filterdMaq"
Same filtering thing can happen inside controller which would help to improve performance as well.
$http.get('data.json').then(function(response){
$scope.dataCopy = response.data; //this is original copy of an maq.
//filtered maq
$scope.maq = $filter('filter')(angular.copy($scope.dataCopy), { index: 0}, true);
});
You don't need to use {{ }}. Just print x.index=='0'

How to avoid ng-init in angular?

I want to show message when ng-repeat collection is empty i.e.:
<div ng-init="filteredArray=(array|filter:{...})">
<h1 ng-if="!filteredArray.length">Empty array</h1>
<table ng-if="filteredArray.length">
<tr ng-repeat="element in filteredArray">
<td>{{element}}</td>
</tr>
</table>
</div>
The problem is that ng-init will not watch for modification of the source array. Any hint how to do it properly?
You can just create the filtered variable in the ng-repeat, and use that one:
<div>
<h1 ng-if="!filteredArray.length">Empty array</h1>
<table ng-if="filteredArray.length">
<!-- here angular assigns the filtered array to the 'filteredArray' variable,
which then can be used -->
<tr ng-repeat="element in filteredArray=(array|filter:{...})">
<td>{{element}}</td>
</tr>
</table>
</div>
See also this jsfiddle
EDIT
If you don't like the ugly expression, you can also do something like this:
function myController ($scope, $filter) {
$scope.$watch("theFilter", function (val) {
$scope.filteredArray = $filter("filter")($scope.array, val);
});
}
And in your html:
<tr ng-repeat="element in filteredArray">
..
</tr>
Check in this jsfiddle
Check ng-repeats $last to show your message like below
<div ng-repeat="n in data track by $index">
<h1 ng-if="$last">Empty array</h1>
</div>
In your case you can have a variable at the table level and then set it to $last,when it'll be true your message will show like below
<body ng-app="app" ng-controller="ctrl">
<div ng-init='counter=false'>
<h1 ng-if='counter'>Empty array</h1>
<table ng-if="myData.length">
<tbody>
<tr ng-repeat="element in myData track by $index" ng-init="counter=$last">
<td>{{element}}
<ng-if ng-init='sync($last)'/>
</td>
</tr>
</tbody>
</table>
</div>
</body>
Your controller should look like below
var app=angular.module('app',[])
app.controller('ctrl',function($scope){
$scope.myData=['a','b','c']
$scope.sync=function(val)
{
alert(val)
$scope.counter=val
}
})
Since you have stored (array|filter:{...}) value into filteredArray, you cannot modify it in the template.
You should repeat (array|filter:{...}) code in the template.
<h1 ng-if="!(array|filter:{...}).length">Empty array</h1>
<table ng-if="(array|filter:{...}).length">
<tr ng-repeat="element in (array|filter:{...})">
<td>{{element}}</td>
</tr>
</table>

Angularjs with ng-repeat to print data separate by ,

I have data in json format, which I would like to display the item on the different data cell based on its first element. If more than one element in the cell, multiple item should be shown separable by "," or .
For example, if my json is:
data = {{"Mon","012"},{"Tue","123"},{"Mon","112"},{"Mon","032"},...}
<table>
<tr>
<td id="Mon"> 012 , 112 , 032 </td>
<td> id="TUe"> 123 </td>
</tr>
</table>
or
<pre>
<table>
<tr>
<td id="Mon"> <div>012</div> <div> 112 </div> <div>032</div> </td>
<td id="TUe"> <div>123</div> </td>
</tr>
</table>
</pre>
I was investigating the doc for ng-repeat with $odd and $index etc., but could not find the right way to get my result.
Your JSON is invalid, so I reformated it a bit to answer the format question.
CSS should do the formatting. You can define a delimiter if there are multiple <span> elements.
td span+span:before {
content: ", ";
}
angular.module('app', [])
.run(function($rootScope) {
$rootScope.dataOrdered = [{
key: "Mon",
values: ["012", "112", "032"]
}, {
key: "Tue",
values: ["123"]
}];
});
table,
th,
td {
border: 1px solid black;
padding: 2px;
}
td span+span:before {
content: ", ";
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<table ng-app="app">
<tr>
<td ng-repeat="item in dataOrdered" id="{item.id}}"><span ng-repeat="value in item.values" ng-bind="value"></span>
</td>
</tr>
</table>

Resources