I am populating data to a table and even if there are more than 10+ rows, it still shows
No data available in the table
I tried different solutions offered in the stack but none worked.
https://datatables.net/forums/discussion/38174/no-data-available-in-table-still-appears-after-rows-are-loaded-data-disappears-on-column-sorted
Data table is showing no data available in table using Angular
My code is available below, any help would be appreciated.
this.detailsService.getJobDetails(this.jobId).subscribe(data => {
this.assetsList = data;
if (this.jobDetails.status === "Queued") {
this.jobRunning = true;
this.jobExpired = false;
} else {
this.jobRunning = false;
this.jobExpired = true;
}
this.startTime = this.timeStamptoTime(this.jobDetails.startTime);
this.endTime = this.timeStamptoTime(this.jobDetails.endTime);
});
<table id="user-table" datatable [dtOptions]="dtOptions" class="row-border hover">
<thead>
<tr>
<th>Asset Id</th>
<th>Title</th>
<th>Status</th>
<th>Updated</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of assetsList">
<td class="ellipsis" title="item.id">{{ item.id }}</td>
<td class="ellipsis-name">{{ item.title }}</td>
<td [ngStyle]="{ color: colorStatus }">
{{ item.status }}
</td>
<td>{{ timeStamptoDateTime(item.startTime) }}</td>
<td>Re-Injest</td>
</tr>
</tbody>
</table>
I used ChangeDetectorRef in error of service but its also not working.
[{"id":"20d2063c-58e3-4391-9971-a7c9bfd6cc66","guid":"2ABs0qlpwoZj","title":"Georgia","type":"MOVIE","description":null,"startTime":1557906022212,"duration":null,"status":"Completed","streamoneId":null,"published":false,"error":null},{"id":"4e409f42-177c-4b0e-a6d7-d3459d2b1a60","guid":"r9wjARFp5ybo","title":"Dead Man Walking","type":"MOVIE","description":null,"startTime":1557906028718,"duration":null,"status":"Completed","streamoneId":null,"published":false,"error":null},{"id":"ca279d00-3a07-48ae-8ff3-efd524060059","guid":"zIVqvJQ80lmE","title":"Taxi Driver","type":"MOVIE","description":null,"startTime":1557906031223,"duration":null,"status":"Completed","streamoneId":null,"published":false,"error":null},{"id":"63aca7dc-17ba-4f4f-a75a-e6667b3e03dc","guid":"OYv845bmL0yA","title":"Unforgettable","type":"MOVIE","description":null,"startTime":1557906034716,"duration":null,"status":"Completed","streamoneId":null,"published":false,"error":null},{"id":"5717d61c-e8dd-4e30-b02e-42c73aa56ff7","guid":"QHbHU1LRNjTQ","title":"GoldenEye","type":"MOVIE","description":null,"startTime":1557906043909,"duration":null,"status":"Completed","streamoneId":null,"published":false,"error":null},{"id":"555de673-88de-4911-8418-600e39253f08","guid":"A4no5EdT4i69","title":"It Takes Two","type":"MOVIE","description":null,"startTime":1557906065093,"duration":null,"status":"Completed","streamoneId":null,"published":false,"error":null},{"id":"b17e412e-5438-450d-8a2d-2f3414c103d5","guid":"hQ1j4MYyyFZA","title":"Sabrina","type":"MOVIE","description":null,"startTime":1557906067911,"duration":null,"status":"Completed","streamoneId":null,"published":false,"error":null},{"id":"4ec72565-72eb-4348-a985-b457ae5318ad","guid":"5glGh59h45IJ","title":"The American President","type":"MOVIE","description":null,"startTime":1557906070579,"duration":null,"status":"Completed","streamoneId":null,"published":false,"error":null},{"id":"c611ed9e-2c27-4795-8317-639037753090","guid":"MZgULmywtVQR","title":"Kids of the Round Table","type":"MOVIE","description":null,"startTime":1557906073218,"duration":null,"status":"Completed","streamoneId":null,"published":false,"error":null},{"id":"a36ef9f8-3154-470e-ac3e-5de68692e026","guid":"itGULjm1tWf9","title":"Across the Sea of Time","type":"MOVIE","description":null,"startTime":1557906076013,"duration":null,"status":"Completed","streamoneId":null,"published":false,"error":null},{"id":"fd444ae6-722d-4959-becf-34417bd0f282","guid":"Ii5YffceXL2n","title":"Don't Be a Menace to South Central While Drinking Your Juice in the Hood","type":"MOVIE","description":null,"startTime":1557906078785,"duration":null,"status":"Completed","streamoneId":null,"published":false,"error":null},{"id":"6074d7c1-a420-45dc-8418-9b3ea20e5bee","guid":"ruPJj6svK7YK","title":"White Squall","type":"MOVIE","description":null,"startTime":1557906082274,"duration":null,"status":"Completed","streamoneId":null,"published":false,"error":null}]
Try this:
Add this.dtTrigger.next() after populating data
dtTrigger: any = new Subject();
this.detailsService.getJobDetails(this.jobId).subscribe(data => {
this.assetsList = data;
this.dtTrigger.next();
...
});
I have a custom directive like this:
<table id="usertbl" class="table table-hover table-bordered" style="
position: relative;
top: 27px;
">
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>gender</th>
<th>state</th>
<th>zip</th>
<th>email</th>
<th>mobile</th>
<th>Delete</th>
</tr>
<tr ng-repeat="x in users">
<td>{{ x.fName }}</td>
<td>{{ x.lName }}</td>
<td>{{ x.gender }}</td>
<td>{{ x.state }}</td>
<td>{{ x.zip }}</td>
<td>{{ x.email }}</td>
<td>{{ x.mobile }}</td>
<td><button class="btn btn-danger" ng-click="clickFunc(x.email)">Delete Customer</button></td>
</tr>
</table>
</body>
http.get("getallusers.do",{ params:{pageno:count,pageSize:2}}).then(function(response) {
//First function handles success
scope.users = response.data;)}
One next button is there each time clicking it will fetch 10 records from the db, but each time the 10 record is added to the existing 10 record in the ui table. i want only new 10 record to be added in the table .
Clear the array and then push the new data as below
scope.users =[];
scope.users = response.data;
You need to call $scope.$apply() after $scope.users = response.data;
$scope.users = response.data;
$scope.$apply()
Working demo
You have to methods to do this
First, you can clear the array and then push the new data
scope.users = [];
scope.users = response.data;
Second, you can splice and insert new data
//This will recreate the array as well
scope.users.splice(0, scope.users.length, ...response.data);
So it will be like this
http.get("getallusers.do",{ params:{pageno:count,pageSize:2}}).then(function(response) {
//First function handles success
scope.users = []
scope.users = response.data;
//OR
scope.users.splice(0, scope.users.length, ...response.data);
)}
UDPATE
What I am assuming from your comments is you are trying to remove values which are same in response.data and users.
You could do something like this.
scope.users = scope.users.filter(function(obj) {
return response.data.indexOf(obj) == -1; });
I have a table that's generated using ng-repeat with some columns headers. On the column headers, I want to columns to be sorted. I included a font-awesome sort icon next to their text and when it's clicked, I call an ng-click with ng-click="sortColumn()". I'm calling this for every column header.
How do I know which column header got clicked on? Right now it fires for each header column.
How do pass the current column in using ng-click?
I tried to pass in this, but it returns the $scope object.
Here's what I have so far:
HTML:
<table class="table">
<thead>
<tr>
<td><b>Product </b><i class="fa fa-sort" ng-click="vm.sortColumn(this)"></i></td>
<td><b>Code </b><i class="fa fa-sort" ng-click="vm.sortColumn(this)"></i></td>
<td><B>Available </b><i class="fa fa-sort" ng-click="vm.sortColumn(this)"></i></td>
<td><B>Price </b><i class="fa fa-sort" ng-click="vm.sortColumn(this)"></i></td>
</tr>
</thead>
<tbody>
{{ vm.noProducts }}
<tr ng-repeat="product in vm.products">
<td>{{ product.productName}}</td>
<td>{{ product.productCode }}</td>
<td>{{ product.releaseDate | date }}</td>
<td>{{ product.price | currency }}</td>
</tr>
</tbody>
</table>
Javascript:
vm.sortColumn = function (obj) {
console.log(obj);
}
I don't think that you can just pass column as object to sortColumn(). If you need column in that function you can loop trough products and make a new array that will be populated for example with all product names.
Maybe that function could look like this:
function getColumn(val){ // 'productName'
var column = [];
for(var i in $scope.products){
column.push(column.push($scope.products[i][val]))
}
return column
}
If you want to sort table you can use orderBy filter.
To your sortColumn() function pass parameter name and in your ng-repeat use orderBy to order column ascending/descending by one of the parameters.
<table class="table">
<thead>
<tr>
<td ng-click="sortColumn('productName')"><b>Product </b></td>
<td ng-click="sortColumn('productCode')"><b >Code </b></td>
<td ng-click="sortColumn('releaseDate')"><b >Available </b></td>
<td ng-click="sortColumn('price')"><b >Price </b></td>
</tr>
</thead>
<tbody>
<tr ng-repeat="product in products | orderBy: criteria">
<td>{{ product.productName}}</td>
<td>{{ product.productCode }}</td>
<td>{{ product.releaseDate | date }}</td>
<td>{{ product.price | currency }}</td>
</tr>
</tbody>
</table>
In your controller set default value for orderBy criteria. (I used here productName)
$scope.criteria = 'productName';
$scope.sortColumn = function(val){
console.log(val)
if($scope.criteria == val){
$scope.criteria = "-"+val;
} else {
$scope.criteria = val;
}
If user clicks on productCode for example, all rows will be sorted by that criteria ascending ('productCode'), if user click on productCode once again all will be sorted descending by criteria '-productCode'
I created small plunker to demonstrate that. Hope it helps.
I need to add rows in table #dynamic but table static shouldn't be affected.
If I click the button with the code below, both tables will be updated, because they have the same v-for. And, if I put a v-for in a v-for my data won't be fetched. I can't figure out how to "unique" the first table.
vue/html:
<template>
<table id="dynamic">
<tr v-for="rows in list">
<td>Content of row {{ rows.item1 }}</td>
<td>Content of row {{ rows.item2 }}</td>
</tr>
</table>
<div #click="block = !block">click</div>
<table id="static">
<tr v-for="rows in list">
<td>Content of row: {{ rows.item3 }}</td>
<td>Content of row: {{ rows.item4 }}</td>
</tr>
</table>
</template>
js
export default {
data: function () {
return {
list: [],
};
},
props: ['channelId'],
mounted() { },
created() {
this.fetchChannel(this.channelId);
},
methods: {
fetchChannel: function (channelId) {
$.getJSON('/api/channel/' + channelId, function (data) {
this.list = data;
}.bind(this));
},
}
}
I found some examples for help like this codepen or fiddle but I am not successful with it.
If the #static table is truly never meant to update when the its data changes, this would be a case for using the v-once directive:
<table id="static" v-once>
<tr v-for="rows in list">
<td>Content of row: {{ rows.item3 }}</td>
<td>Content of row: {{ rows.item4 }}</td>
</tr>
</table>
This will tell Vue to render the table only once and then ignore it upon any re-renders.
Here's a fiddle.
I'm using a Angular.js on the front end to populate a table. I want to use ng-switch to display only data that has specific data in one column, for example only show ‘week 1’ data from a list of a NFL schedule, where one column in the data is Weeks.
So right now this code doesn't show anything in the table. If anyone could help explain this it would be greatly appreciated. Maybe I should be using ng-if ? Maybe I should have a button to press to show week 1, week 2 etc.. What's the best solution for this type of situation?
Here's the controller..
// #########################
// Predictions Controller
// #########################
BLV_app.controller('PredictionsController', function($scope, PredictionsFactory, $routeParams) {
PredictionsFactory.getPredictions(function(data) {
$scope.predictions = data;
});
});
Here's the factory..
// ---------------------------
// Prediction Factory
// ---------------------------
BLV_app.factory('PredictionsFactory', function($http) {
var factory = {};
var predictions = [];
factory.getPredictions = function(callback) {
$http.get('/predictions').success(function(output) {
predictions = output;
console.log("prediction factory", predictions);
callback(output);
});
};
return factory;
});
Here's the html..
<table class="table-striped" id="table-style">
<thead id="table-header">
<tr>
<th class="text-center">HomeTeam</th>
<th class="text-center">AwayTeam</th>
<th class="text-center">Prediction</th>
<th class="text-center">Result</th>
</tr>
</thead>
<tbody ng-repeat="predict in predictions" >
<div ng-model="predict.Week"></div>
<tr ng-switch="predict.Week">
<div ng-switch-when="1">
<td ng-if="$odd" style="background-color:#f1f1f1">{{ predict.HomeTeam }}</td>
<td ng-if="$even">{{ predict.HomeTeam }}</td>
<td ng-if="$odd" style="background-color:#f1f1f1">{{ predict.AwayTeam }}</td>
<td ng-if="$even">{{ predict.AwayTeam }}</td>
<td ng-if="$odd" style="background-color:#f1f1f1">{{ predict.Prediction }}</td>
<td ng-if="$even">{{ predict.Prediction }}</td>
<td ng-if="$odd" style="background-color:#f1f1f1">{{ predict.Result }}</td>
<td ng-if="$even">{{ predict.Result }}</td>
</div>
</tr>
</tbody>
</table>
I believe there is something wrong with ng-repeat and ng-switch when binding to elements like tbody and td. Replace them with div and li makes it working properly: JSFiddle.
<div ng-repeat="predict in predictions">
<div ng-model="predict.id"></div>
<div ng-switch="predict.id">
<div ng-switch-when="1">
<li ng-if="$odd" style="background-color:#f1f1f1">{{ predict.name }}</li>
......
Changing from <div ng-repeat="predict in predictions"> to <tbody ng-repeat="predict in predictions"> makes it not working: JSFiddle.
In ng-repeat docs and ng-switch docs, it says:
Usage
as attribute:
<ANY
ng-repeat="">
...
</ANY>
But obviously they cannot be used on ANY elements.