ng-repeat isn't showing json object items - javascript

I would like to know why my items aren't showing on the DOM. Although ng-repeat is making new table rows. When I console log books it shows up fine but not with ng-repeat. Console Log
HTML
<table class="table table-bordered table-light table-hover">
<tbody id="tableBookSearch">
<tr ng-repeat="(key, value) in books"><td>key : {{key}} value: {{value}}</td></tr>
</tbody>
</table>
JS
$.getJSON(googleAPI, function(response){
$scope.books = [];
for(var i = 0; i < response.items.length; i++){
$scope.books.push(response.items[i]);
console.log('pushed book : ' + i);
}
$scope.$apply();
console.log('scope applied');
console.log($scope.books);
});
UPDATE:
I tried doing this with a normal array and it also didn't show data. The reference isn't null either.

<table class="table table-bordered table-light table-hover">
<tbody id="tableBookSearch">
<tr ng-repeat="(key, prop) in books">
<td> Key : {{key}}</td>
<td ng-repeat="value in books[key]> value : {{value }}</td>
</tr>
</tbody>
</table>
https://www.w3schools.com/angular/ng_ng-repeat.asp

Instead using ng-repeat go for ng-options in angular find #https://docs.angularjs.org/api/ng/directive/ngOptions

The environment I'm coding in is Angular2 and I thought it to be AngularJS. ng-repeat is a directive of AngularJS and to do something similar I would have to use *ngfor.

Related

Is it possible to have both orderBy and filter for the same table in AngularJS?

In my table it works fine orderBy (descending and ascending). It looks like this:
<table class="table table-striped top-scroll__content">
<thead>
<tr>
<th ng-click="$ctrl.sorting('Name')">Name</th>
<th ng-click="$ctrl.sorting('Type')">Occurence</th>
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="rows in $ctrl.alertsResponse | orderBy:$ctrl.sort.active:$ctrl.sort.descending track by $index">
<td>{{rows.Name}}</td>
<td>{{rows.Type}}</td>
</tr>
</tbody>
</table>
I added a dropdown selector from whom I select a type and I want the table to show only the rows having the selected type.
The JS function works well, it returns the desired result in console and looks like this:
updateFilter(type) {
debugger;
if (type === "0") return this.alertsResponse;
return this.alertsResponse.filter(function(item) {
return item.Type === type;
});
}
My problem comes when I want to add this functionality to the table. I tried to add the filer in the same place as orderBy but probably it is not the right way:
<tr ng-repeat="rows in $ctrl.alertsResponse | orderBy:$ctrl.sort.active:$ctrl.sort.descending track by $index | filter:$ctrl.updateFilter(Type)">
Any suggestions?
No need to pass controller function in filter just pass drop down selector text in filter instead of drop down selector value
ng-model of drop down should be **type**
<tr ng-repeat="rows in $ctrl.alertsResponse | orderBy:$ctrl.sort.active:$ctrl.sort.descending track by $index | filter:Type">
OR
You can filter your data by passing object in filter like
<tr ng-repeat="rows in $ctrl.alertsResponse | orderBy:$ctrl.sort.active:$ctrl.sort.descending track by $index | filter:{Type:type}">
angular.module('myApp', []).controller('namesCtrl', function($scope) {
$scope.rows = [
{Type:1, name:'Tom'},
{Type:2, name:'Jerry'},
{Type:2, name:'Dom'},
{Type:1, name:'Apple'}
];
$scope.type = "1";
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<div ng-app="myApp" ng-controller="namesCtrl">
<select ng-model="type">
<option value="1">Tom</option>
<option value="2">Jerry</option>
</select>
<table border="1" style="margin-top:20px">
<thead>
<tr>
<th >Name</th>
<th >Occurence</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="rows in rows | filter:{Type:type}">
<td>{{rows.name}}</td>
<td>{{rows.Type}}</td>
</tr>
</tbody>
</table>
</div>

How to iterate over filtered rows in Angular datatable

Lets say, I have simple datatable
<table datatable="" dt-options="dtOptions" dt-column-defs="dtColumnDefs" class="row-border hover">
<thead>
<th>ID</th>
<th>Name</th>
</thead>
<tbody>
<tr ng-repeat"reservation in reservations">
<td>{{reservation.ID}}</td><td>{{reservation.name}}</td>
</tr>
</tbody>
</table>
When I put some string into search box datatable is being filtered. Now I want to iterate in Angular over filtered rows and read IDs to array. How to deal with it in Angular? I can use jquery but I do not want make a mess in code.
$scope.addressDTInstance = {};
var j = $scope.addressDTInstance.DataTable.rows();
<table id="addressSelectionTable" class="table table-condensed table-bordered" datatable="ng" dt-options="addressdtOptions" dt-column-defs="addressdtColumnDefs" dt-instance="addressDTInstance">
This is something to get you on your way. Need an instance of dtInstance which you don't have. So add dt-instance='dtInstance' in the html table tag.
Then initiate it at the top of your controller, $scope.dtInstance = {};.
Perform a click or some action in your javascript that you can set a break point on and then examine your $scope.dtInstance to see what all properties and methods you have. As you see in my snippet I'm accessing DataTable.Rows of my dtInstance. If you need better example or help let leave me a comment and I'll revise.
UPDATE
Here is a method I found that works. I am ofcourse using the DTOptionsbuilder. This will get called twice, first when it is created and second when i populated the array variable that is populating my table. I just check to see if rows exist and that the first one isn't 'No results'.
$scope.addressdtOptions = DTOptionsBuilder.newOptions()
.withOption('bFilter', false)
.withOption('bInfo', false)
.withOption('paging', false)
.withOption('processing', true)
.withOption('aaSorting', [1, 'asc'])
.withOption('language', { zeroRecords: 'No results' })
.withOption('initComplete', function () {
var rows = $("#addressSelectionTable > tbody > tr");
if (rows.length > 0 && rows[0].innerText !== "No results") {
var x = 3;
}
});
Here i am setting that variable that is ng-repeat for table. You may not be doing it my way, but you should be able to figure it out for your way.
$.when($OfficerService.GetAddressSelections($scope.officer.EntityID, $scope.officer.EntityTypeID, $scope.officer.MemberID)).then(function (result) {
$scope.addresses = result.data;
$scope.$applyAsync();
});
<table id="addressSelectionTable" class="table table-condensed table-bordered" datatable="ng" dt-options="addressdtOptions" dt-column-defs="addressdtColumnDefs" dt-instance="addressDTInstance">
<thead>
<tr>
<th></th>
<th>Type</th>
<th>Address</th>
<th>City</th>
<th>State</th>
<th>Zip</th>
<th>Country</th>
<th></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="a in addresses">
<td class="centerColumn">
<input type="button" class="btn btn-primary" value="Select" ng-click="selectAddress(a.AddressID,a.AddressLocationCode,$event)" />
</td>
<td>
<span ng-if="a.AddressLocationCode == 'E'">Office</span>
<span ng-if="a.AddressLocationCode == 'M'">Member</span>
</td>
<td>
{{a.AddressLine1}}
<span ng-if="a.AddressLine2 != null"><br /> {{a.AddressLine2}}</span>
</td>
<td>{{a.City}}</td>
<td>{{a.StateCode}}</td>
<td>{{a.Zip}}</td>
<td>{{a.CountryCode}}</td>
<td>{{a.AddressID}}</td>
</tr>
</tbody>
</table>
For me it works: $scope.dtInstance.DataTable.rows( { search: 'applied' } ).data()

How do I get the total sum in ng-init and ng-repeat - angularjs

Having a problem with in ng-init and ng-repeat angularjs
i'm trying to loop the fields rates to get the total
for example this is my table
nane +++++++id+++++++rate
joe +++++++++1+++++++3
joe +++++++++2+++++++3
joe +++++++++3+++++++3
joe +++++++++4+++++++3
this my code.
<table>
<tr>
<td>name</td>
<td>rate</td>
</tr>
<tr ng-repeat="item in videos">
<td>{{item.name}}</td>
<td ng-init="videos.total.rate = videos.total.rate + item.rate">{{item.rate}}</td>
</tr>
<tr>
<td>Total</td>
<td>{{videos.total.rate}}</td>
</tr>
The Result that I get is 3333 instead of 12 when added all together
this is the line with problem
<td ng-init="videos.total.rate = videos.total.rate + item.rate">{{item.rate}}</td>
if i change it to a number it works fine.
<td ng-init="videos.total.rate = videos.total.rate + 3">{{item.rate}}</td>
your help would be great.thanks
Try something like this in controller.
JS
$scope.RateTotal= 0;
for (var i = 0; i < data.length; i++) {
$scope.RateTotal= $scope.RateTotal + data[i].rate;
}
HTML
<p>{{RateTotal}}</p>
Option above is better, but if you want use ng-init use something like this.
<table ng-init="RateTotal = 0">
<thead>
<th>Rate</th>
</thead>
<tbody>
<tr ng-repeat="item in videos">
<td ng-init="$parent.RateTotal= $parent.RateTotal + item.rate">{{item.rate}}</td>
</tr>
<tr>
<thead>
<tr>
<th>Total</th>
<th>{{RateTotal}}</th>
</tr>
</thead>
</tr>
</tbody>
</table>
P.S.
This directive can be abused to add unnecessary amounts of logic into
your templates. There are only a few appropriate uses of ngInit, such
as for aliasing special properties of ngRepeat, as seen in the demo
below; and for injecting data via server side scripting. Besides these
few cases, you should use controllers rather than ngInit to initialize
values on a scope. - ngInit
move this logic into the controller. That is what it is for. The view should be displaying data.
Now you have to worry about how to cast strings to an integer and writing 4x more code in a language that angular must interpret into javascript.
The complexity you are adding here is going to be fun to maintain.
but you probably want to continue doing it wrong, in which case this should work: <table ng-init='videos.total = {"rate": 0}'>
Define a filter to calculate the total:
app.filter('calculateRateTotal',function(){
return function(input){
var total = 0;
angular.forEach(input,function(value,key){
total = total+value.rate;
});
return total;
};
});
HTML:
<td ng-bind="videos | calculateRateTotal"></td>
After 10hrs of no luck just my managed to get it right. turned to be very simple.
This is the code.
In the Controller added
$scope.getTotal = function(){
var total = 0;
for(var i = 0; i < $scope.videos.length; i++){
var item = $scope.videos[i];
total += (item.rate*1);
}
return total; }
And HTML
<table>
<tr>
<th>Rate</th>
</tr>
<tr ng-repeat="item in videos">
<td>{{item.rate}}</td>
</tr>
<tr>
<td>Total: {{ getTotal() }}</td>
</tr>
</table>
Thanks everyone for helping

From DB they are sending HTML, how to render it in the DOM?

I am receiving an object like this
[
{
"BET": 57630343,
"CUSTOMER": 181645,
"SPORT": "MLB",
"XX_FILL OPEN": "<button class=\"btn\" onclick=\"fillOpen(57630343)\">Fill Open</button>",
"XX_VIEW": null,
"XX_CANCEL": "<input type=\"checkbox\" name=\"sports\" value=\"soccer\" onchange=\"fillOpen(57630343)\"/>"
},...]
I am rendering that object in the DOM, but for now, looks like in the picture below
here is the HTML part for the dynamic table
<table>
<thead>
<tr>
<th ng-repeat="column in cols" ng-init="isXX = column.indexOf('XX') === 0">
<span ng-if="isXX">{{column.substring(3).replace('_', ' ')}}</span>
<span ng-if="!isXX">{{column}}</span>
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in rows">
<td ng-repeat="column in cols">
<span>{{row[column]}}</span>
</td>
</tr>
</tbody>
</table>
and here is the Angular part
ReportsFactory.pendingBets(reportParam).then(function(data) {
if (data.length) {
gridInfo = _.forEach(data, function(item) {return item;});
$scope.rows = gridInfo;
$scope.cols = Object.keys($scope.rows[0]);
}
}
The Database guys are sending me that data as you see it in the json I pasted above.
what I need to know, is, what should I do in order to render those elements in the DOM ?
You can use ngBindHtml for that.
<tbody>
<tr ng-repeat="row in rows">
<td ng-repeat="column in cols" ng-bind-html="row[column]">
</td>
</tr>
</tbody>
Since you're getting the HTML from a $http call, you have to use $sce.trustAsHtml to correctly display this HTML on every single one of your row columns that require this:
$scope.rows.forEach(function(row) {
for (var key in row) {
if (key.indexOf('XX') === 0) {
var value = row[key];
if (value) {
row[key] = $sce.trustAsHtml(value);
}
}
}
});
Here's a working plunkr:http://plnkr.co/edit/7iFUhjg6Q0YIwRi47fDm?p=preview
You can do it by using ngSanitize.
Check it here. https://docs.angularjs.org/api/ngSanitize
Then, you can use ng-bind-html directive, which render HTML code to DOM element.
And, Javascript in the element can be applied with trustAsHtml method of $sce service.
I made an example here.
http://plnkr.co/edit/sTEUIWHwGXSAUSQ2rC8y?p=preview

AngularJS in HTML table

I want to create a table with products on a certain menu of a store.
The table is divided by categories (product categories) and for every category the desired products should be shown under his category.
Something like:
I am able to get the different categories in my html but when I want to use ng-repeat on table rows or table headers I get nothing...
<table class="table table-hover">
<tr>
<th colspan="5">Menu items</th>
</tr>
<tr ng-app="categories" ng-cloak="" ng-controller="category" ng-repeat= "c in categories">
<th>{{c[1]}}</th>
</tr>
AngularJS
categories = angular.module('categories', []);
categories.controller("category",function($scope, $http){
var serviceBase = 'api/';
$http.get(serviceBase + 'categories').then(function (results) {
$scope.categories = results.data;
for(var i = 0; i < $scope.categories.length; i++){
var categories = $scope.categories[i];
}
});
});
What is going wrong here?
Try this following code:
categories = angular.module('categories', []);
categories.controller("category",function($scope, $http){
var serviceBase = 'api/';
$http.get(serviceBase + 'categories').then(function (results) {
var categorie = results.data;
for(var i = 0; i < categorie.length; i++){
$scope.categories = categorie[i];
}
});
});
I found the solution myself:
<table ng-app="categories" ng-cloak="" ng-controller="category">
<tr>
<th>Menu items</th>
</tr>
<tr ng-repeat= "c in categories">
<th>{{c[1]}}</th>
</tr>
You shouldn't have ng-repeat of on your ng-app & ng-controller div. Even you don't need to do for loop. You categories does have category in it. You can access those inside ng-repeat using c only no need to specifying any index in it.
Markup
<body class="table table-hover" ng-app="categories" ng-cloak="" ng-controller="category" >
<tr>
<th colspan="5">Menu items</th>
</tr>
<tr ng-repeat="c in categories">
<th>{{c}}</th>
</tr>
</table>
</body>

Categories

Resources