Objects in Array not showing in ng-repeat - AngularJS - javascript

I'm quite new to AngularJS and I'm facing some problems showing objects from an array in my view.
I have the following javascript code:
// list initialization:
vm.latestInvoices = { invoices: []};
....
// adding function to viewmodel:
vm.getLatestInvoices = getLatestInvoices;
...
function getLatestInvoices() {
console.log("Test 1234");
var servicename = "GetLatestInvoicesRequest";
var params = {};
httpCall(servicename, params).then(function (data) {
vm.latestInvoices = data;
console.log(data);
return vm.latestInvoices;
})["catch"](function (data) {
console.log("getLatestInvoices error");
});
}
My HTML view:
<div class="col-lg-12">
<p id="overview-headline">Invoices Overview</p>
<div class="scrollCustomers" ng-init="vm.getLatestInvoices()">
<table class="table table-hover">
<thead>
<tr>
<th>Client</th>
<th>Project</th>
<th>ID</th>
<th>Inv. Date</th>
<th>Start Date</th>
<th>End Date</th>
<th>DKK ex VAT</th>
<th>CIG</th>
<th>Attention</th>
<th>Cust. Manager</th>
<th>Regarding</th>
<th>Due Date</th>
<th>Finalized</th>
<th>Paid</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="invoice in invoices">
<td>{{invoice.CompanyName}}</td>
<td>Project Name</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>Default</td>
<td></td>
<td></td>
<td></td>
<td>N/A</td>
<td>N/A</td>
<td>N/A</td>
</tr>
</tbody>
</table>
</div>
</div>
In the Google Dev console, the array and it's objects are returned fine. The view doesnt return the default values, Project Name, Default and N/A, so my guess is that for some reason, invoices in ng-repeat is never called?
Thanks in advance!

Attach the result to the $scope:
httpCall(servicename, params).then(function (data) {
vm.latestInvoices = data;
console.log(data);
$scope.invoices = data;
})["catch"](function (data) {
console.log("getLatestInvoices error");
});
}

Related

How to use *ngIf condition inside the <td> field of table using angular where *ngFor is looping?

Actually in my component.ts file i have used the api to call the method and it is returning me array of objects.
And my problems began as I m trying to use ngIf in tag to hide/show column according to the client.auditorGroup as it is either true or false(it is of type boolean) but it is not giving me access:
1st code:
ngOnInit() {
this.http.get('http://localhost:8080/api/selections')
.subscribe((data: any[]) => {
this.clients = data;
console.log(this.clients);
this.chRef.detectChanges();
const table: any = $('table');
this.dataTable = table.DataTable();
});
}
And in my html code I have used this Edit Delete and it is h
<table class="table table-bodered">
<thead>
<tr>
<th>Mag No</th>
<th>SelectionDate</th>
<th> SelectedBy</th>
<th>PanEximNumber</th>
<th>Name</th>
<th>Address</th>
<th>PhoneNumber</th>
<th>SelectionType</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let client of clients">
<td>{{client.selectionId}}</td>
<td>{{client.selectionDate}}</td>
<td>{{client.selectedBy}}</td>
<td>{{client.panEximNumber}}</td>
<td>{{client.name}}</td>
<td>{{client.address}}</td>
<td>{{client.phoneNumber}}</td>
<td>{{client.selectionType}}</td>
<td *ngIf="{{client.auditorGroup}}==false">Edit Delete</td>
</tr>
</tbody>
</table>
Remove the interpolation {{}} when using *ngIf
<td *ngIf="!client.auditorGroup">Edit Delete</td>

How to make footable work in a table that's being populated with JS from JSON?

I have something like this:
<table id="thatTable" class="table toggle-circle">
<thead>
<tr>
<th>ID</th>
<th>FieldA</th>
<th data-hide="all">FieldB</th>
<th data-hide="all">FieldC</th>
</tr>
</thead>
<tbody>
</tbody>
<tfoot>
<tr>
<td colspan="4">
<div class="text-right">
<ul class="pagination"></ul>
</div>
</td>
</tr>
</tfoot>
</table>
Then a JS like this:
var fillThatTable = function (list) {
$.each(list, function (index, item) {
$('#thatTable tbody').append($('<tr>')
.append($('<td>').text(item.ID))
.append($('<td>').text(item.FieldA))
.append($('<td>').text(item.FieldB))
.append($('<td>').text(item.FieldC))
)
);
});
};
Everything works fine, the table gets the data and shows it all. Problem comes when I want to set footable() to that table, like so:
$(document).ready(function () {
fillThatTable();
$('#thatTable').footable();
});
And instead of getting something beautiful, I just receive an average filtered table, almost like I didn't put that $('#thatTable').footable(). I checked the JS are imported, they are. Is it maybe because the table doesn't have anything in the tbody? What am I missing?
Dream:
Reality:
I've updated PM's fiddle to make an easier use of FooTable: http://jsfiddle.net/0pb4x7h6/1
If your html changes to this:
<table id="thatTable" class="table toggle-circle">
<thead>
<tr>
<th data-name="ID">ID</th>
<th data-name="FieldA">FieldA</th>
<th data-name="FieldB" data-breakpoints="all">FieldB</th>
<th data-name="FieldC" data-breakpoints="all">FieldC</th>
</tr>
</thead>
<tbody>
</tbody>
<tfoot>
<tr>
<td colspan="4">
<div class="text-right">
<ul class="pagination"></ul>
</div>
</td>
</tr>
</tfoot>
</table>
Then you can simplify your script to this:
$(document).ready(function () {
var list = [
{"ID":"1","FieldA":"A1","FieldB":"B1","FieldC":"C1"},
{"ID":"2","FieldA":"A2","FieldB":"B2","FieldC":"C2"},
{"ID":"3","FieldA":"A3","FieldB":"B3","FieldC":"C3"}
];
// No need for this
//fillThatTable();
$('#thatTable').footable({
rows: list
});
});

.parents() not work on table

I'm trying show user details in user list using AJAX JQuery, but it does not work as I need.
It works for my first details in the same tr, but doesn't work in the second detail in td in the second row. How should I do it properly?
Here is the code:
My view:
<table class="table">
<thead>
<th>#</th>
<th>name</th>
<th>password</th>
<th></th>
</thead>
<tbody>
#foreach($users as $user)
<tr>
<table class="table">
<tr>
<td>{{$user->id}}</td>
<td>{{$user->name}}</td>
<td>{{$user->password}}</td>
<td class="extend-user" data-details="0" data-url="{{route("user", ["id" => $user->id])}}">Details</td>
<td id="details">a</td>
</tr>
<tr>
<td colspan="5" id="details">a</td>
</tr>
</table>
</tr>
#endforeach
</tbody>
</table>
and my script:
$(".extend-user").click(function() {
var self = this;
if($(self).data("details")===0)
$.ajax({
method: "POST",
url: $(self).data("url"),
data: {
_token: $("#_token").val()
},
success: function(data) {
$(self).parents().find("#details").append(data["name"]);
//$(self).parent().parent().find("#details").append(data["name"]);
//$(self).closest('table').find("#details").append(data["name"]);;
$(self).data("details", "1");
}
});
if($(self).data("details")===1) {
$(self).data("details", "0");
$(self).parent().find("p.details").html("");
}
});
try to use $(self).closest("table").find("#details").append(data["name"]);
closest finds the closest parent element that you want to find.
replace $(self).parents().find("#details").append(data["name"]);
with
$(self).parents('tr').find("#details").append(data["name"]);

Angular.js smart table loading symbol during ajax call

Using the pipe/ajax plugin example at http://lorenzofox3.github.io/smart-table-website I have been trying to implement an Angular.js smart table with a loading indicator whilst my ajax call is still loading.
angular-boostrap.js
var eposWebAngularStrutsApp = angular.module('eposWebAngularStrutsApp', ['ngResource','smart-table']);
angular-controller.js
eposWebAngularStrutsApp.controller('StoreHealthCheckController', ['$scope','StoreServerHealth', function ($scope, StoreServerHealth) {
//http://www.sitepoint.com/creating-crud-app-minutes-angulars-resource/
var ctrl = this;
this.displayed = [];
this.callServer = function callServer(tableState) {
ctrl.isLoading = true;
StoreServerHealth.query(function(result) {
ctrl.displayed = result.data;
ctrl.isLoading = false;
}); //query() returns all the entries
};
}]);
angular-service.js
eposWebAngularStrutsApp.factory('StoreServerHealth', function($resource) {
return $resource('json/storeHealthCheckList.action'); // Note the full endpoint address
});
My JSP...
<table class="table table-striped" st-pipe="mc.callServer" st-table="mc.displayed" ng-controller="StoreHealthCheckController">
<thead>
<tr>
<th>Store</th>
<th>Server</th>
<th>Conn Status</th>
<th>Last Updated</th>
<th>MDI</th>
<th>Last Synched (MDI)</th>
<th>DSM</th>
<th>Last Synched (DSM)</th>
<th>Trading Status</th>
<th>Build</th>
</tr>
</thead>
<tbody ng-show="!mc.isLoading">
<tr ng-repeat="row in mc.displayed">
<td>{{row.locationId}}</td>
<td>{{row.clientId}}</td>
<td>{{row.status}}</td>
<td>{{row.displayLastUpdateTime}}</td>
<td>{{row.replicationStatus}}</td>
<td>{{row.displayLastReplicationSyncTime}}</td>
<td>{{row.dsmReplicationStatus}}</td>
<td>{{row.dsmLastSynchTime}}</td>
<td>{{row.storeTradingStatus}}</td>
<td>{{row.buildVersion}}</td>
</tr>
</tbody>
<tbody ng-show="mc.isLoading">
<tr>
<td colspan="10" class="text-center">Loading ... </td>
</tr>
</tbody>
</table>
But I keep getting an error TypeError: href is null firebug/content/debugger/stackFrame/StackFrame.js.
Can someone let me know what I might be doing wrong here.
Thanks
The comment posted above was the answer to this question. I had forgotten to Alias the controller.

Javascript <tbody> swapping not working

I've got a couple tables whose content should change based on clicking certain buttons (in this case, links). I've used this Javascript code elsewhere successfully, though with only one parameter in the switchid() function (there was only one table to mess around with). I keep researching examples of this and I seem to be passing the variables correctly, so what am I doing wrong? This code doesn't work on Chrome or IE:
Edit: Per the comments, I was able to whittle my javascript section down to a single, smaller function, that should do the same thing. I have made the change below. It still doesn't work, though.
I also changed my "array" and "x" variables to "JonArray" and "JonX" to avoid any chances of one of those being a reserved word.
<!DOCTYPE html>
<html>
<body>
<script type="text/javascript">
var topTable = new Array('English','Spanish');
var bottomTable = new Array('Japanese','Italian');
function switchid(JonArray,JonX) {
for(var i=0;i<JonArray.length();i++) {
document.getElementById(JonX).style.display='none';
}
document.getElementById(JonX).style.display='table-row-group';
}
</script>
<table border='1'>
<thead>
<tr><td>Odds</td><td>Evens</td></tr>
</thead>
<tfoot>
<tr><td>English</td><td>Spanish</td></tr>
</tfoot>
<tbody id='English'>
<tr><td>One</td><td>Two</td></tr>
<tr><td>Three</td><td>Four</td></tr>
</tbody>
<tbody id='Spanish' style="display:none;">
<tr><td>Uno</td><td>Dos</td></tr>
<tr><td>Tres</td><td>Quatro</td></tr>
</tbody>
</table>
<br />
<table border='1'>
<thead>
<tr><td>Odds</td><td>Evens</td></tr>
</thead>
<tfoot>
<tr><td>Japanese</td><td>Italian</td></tr>
</tfoot>
<tbody id='Japanese'>
<tr><td>Ichi</td><td>Ni</td></tr>
<tr><td>San</td><td>Shi</td></tr>
</tbody>
<tbody id='Italian' style="display:none;">
<tr><td>Un</td><td>Due</td></tr>
<tr><td>Tre</td><td>Quattro</td></tr>
</tbody>
</table>
</body>
</html>
http://jsfiddle.net/92ZPM/1/
I made sure the function and variables were available regardless of when they are created.
I also gave your variables descriptive names, cleaned up and stored the table data in a single object.
JavaScript
window.switchid = function (table, language) {
var tables = {
'top': ['English', 'Spanish'],
'bottom': ['Japanese', 'Italian']
};
for (var i = 0; i < tables[table].length; i++) {
document.getElementById(tables[table][i]).style.display = 'none';
}
document.getElementById(language).style.display =
'table-row-group';
}
HTML
<table border='1'>
<thead>
<tr>
<td>Odds</td>
<td>Evens</td>
</tr>
</thead>
<tfoot>
<tr>
<td>English
</td>
<td>Spanish
</td>
</tr>
</tfoot>
<tbody id='English'>
<tr>
<td>One</td>
<td>Two</td>
</tr>
<tr>
<td>Three</td>
<td>Four</td>
</tr>
</tbody>
<tbody id='Spanish' style="display:none;">
<tr>
<td>Uno</td>
<td>Dos</td>
</tr>
<tr>
<td>Tres</td>
<td>Quatro</td>
</tr>
</tbody>
</table>
<br />
<table border='1'>
<thead>
<tr>
<td>Odds</td>
<td>Evens</td>
</tr>
</thead>
<tfoot>
<tr>
<td>Japanese
</td>
<td>Italian
</td>
</tr>
</tfoot>
<tbody id='Japanese'>
<tr>
<td>Ichi</td>
<td>Ni</td>
</tr>
<tr>
<td>San</td>
<td>Shi</td>
</tr>
</tbody>
<tbody id='Italian' style="display:none;">
<tr>
<td>Un</td>
<td>Due</td>
</tr>
<tr>
<td>Tre</td>
<td>Quattro</td>
</tr>
</tbody>
</table>
you have to change your javascript a little:
var tables=new Array();
tables['topTable'] = new Array('English','Spanish');
tables['bottomTable'] = new Array('Japanese','Italian');
function switchid(JonArray,JonX) {
//alert(JonArray);
var tmptable=tables[JonArray];
for(var i=0;i < tmptable.length;i++) {
document.getElementById(tmptable[i]).style.display='none';
}
document.getElementById(JonX).style.display='';
}
Some of these answers work, but I just caught the REAL answer via Chrome DevTools! In my 'for' loop I was using 'length()' instead of 'length'!!!
Why not to use CSS instead of looping through IDs?
JSFiddle
HTML
<table border='1' class="English">
<thead>
<tr><td>Odds</td><td>Evens</td></tr>
</thead>
<tfoot>
<tr><td onclick="changeLang(this,'English')">English</td><td onclick="changeLang(this,'Spanish')">Spanish</td></tr>
</tfoot>
<tbody id='English'>
<tr><td>One</td><td>Two</td></tr>
<tr><td>Three</td><td>Four</td></tr>
</tbody>
<tbody id='Spanish'>
<tr><td>Uno</td><td>Dos</td></tr>
<tr><td>Tres</td><td>Quatro</td></tr>
</tbody>
</table>
CSS
tbody {
display: none;
}
.English #English, .Spanish #Spanish, .Japanese #Japanese, .Italian #Italian {
display: table-row-group;
}
JS
function changeLang(cell, lang) {
cell.parentNode.parentNode.parentNode.className = lang;
}

Categories