How to print Vue objects row by row - javascript

I have a Vue application and I am trying to display each 'object' in its own table row. However, I can only get it to display each object in one column or I can get it to a point where each element is in its own row (image below). How would I make it so '0 BTC AUD 14,745.3' is in the first row and then the next object '1 ETH AUD 312.14' is displayed in the second row. I am new to Vue and was wondering if anyone was able to help me out
I have attached an image below as well as my current code, thank you!
<template>
<div class="main">
<div id="container" v-for="(index) in coin" :key="index">
<table class="coins">
<thead>
<tr class="header">
<th>Rank</th>
<th>Name</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<td>{{ index }}</td>
</tbody>
</table>
</div>
</div>
</template>
<script>
import axios from 'axios'
var limit = 20
export default {
name: 'ex',
data: () => ({
coin: []
}),
created () {
axios.get('https://min-api.cryptocompare.com/data/top/totalvolfull?limit=' + limit + '&tsym=AUD')
.then(response => {
for (var i = 0; i < limit; i++) {
this.coin.push(i, response.data.Data[i].CoinInfo.Name, response.data.Data[i].DISPLAY.AUD.PRICE)
// console.log(this.coin[i])
}
})
.catch(e => {
this.errors.push(e)
})
}
}
</script>

Change the way you are pushing data into your coin array, because here in every iteration you are pushing three items (an index, a coin name and a value) into the array but what you want to do is push a single item (an array or object) containing all this information. For code clarity also change the name of the coin array into coins. Something like this should work:
this.coins.push([i, response.data.Data[i].CoinInfo.Name, response.data.Data[i].DISPLAY.AUD.PRICE])
Then change the iteration in your template. First thing change the v-for to something like this:
<div id="container" v-for="(coin, index) in coins" :key="index">
and then when you print the content:
<tbody>
<td>{{ coin[0] }}</td>
<td>{{ coin[1] }}</td>
<td>{{ coin[2] }}</td>
</tbody>
I didn't test this, but I hope the general idea is enough to get you on the right direction.

maybe change how did you create this object
instead do that:
this.coin.push(i, response.data.Data[i].CoinInfo.Name, response.data.Data[i].DISPLAY.AUD.PRICE)
Do something like that
const coinObject = {
index: i,
name:response.data.Data[i].CoinInfo.Name,
price: response.data.Data[i].DISPLAY.AUD.PRICE
}
this.coin.push(coinObject);
and then you can loop like that in your template:
<div id="container" v-for="(coinItem, index) in coin" :key="index">
<table class="coins">
<thead>
<tr class="header">
<th>Rank</th>
<th>Name</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<td>{{ coinItem.index }}</td>
<td>{{ coinItem.name }}</td>
<td>{{ coinItem.price }}</td>
</tbody>
</table>
</div>

Related

Data table still showing No data even if data is filled

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();
...
});

How to remove old data and bind new data to a table while using ng-repeat?

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; });

Get place in table of icon using ng-click

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.

Add row to one table but not the other with v-for in Vue

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.

Using ng-switch to populate a table

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.

Categories