I need to create a table with Vue and the data are from a JSON. I don't know how to set for the td table tag the "Jogosultsagok" two "Nev" values.
I tried row.Jogosultsagok[0].Nev format, but this not work, I write down the code parts and the final error for this.
HTML
<tbody>
<tr v-for="row in get_rows()">
<td>{{row.Id}}</td>
<td>{{row.Nev}}</td>
<td>{{row.Jogosultsagok[0].Nev}}</td>
<td>{{row.Jogosultsagok[1].Nev}}</td>
</tr>
</tbody>
Vue
data: {
rows:[]
},
created:function() {
fetch('https://api.myjson.com/bins/7jr55')
.then(res => res.json())
.then(res => {
this.rows = res;
})
},
methods: {
"get_rows": function get_rows() {
var start = (this.currentPage-1) * this.elementsPerPage;
var end = start + this.elementsPerPage;
return this.rows.slice(start, end);
},
},
JSON
[
{
"Id": 1,
"Nev": "László",
"Jogosultsagok": [
{
"Id": 1,
"Nev": "Módosítás"
},
{
"Id": 2,
"Nev": "Olvasás"
}
],
"Eletkor": 25,
"Regisztralt": "2019-01-31 06:45:51.557Z",
"Munkahely": {
"Id": 12,
"Nev": "Cég 1"
}
},
{
"Id": 2,
"Nev": "Péter",
"Jogosultsagok": [
{
"Id": 2,
"Nev": "Olvasás"
}
],
"Eletkor": 44,
"Regisztralt": "2011-01-31 09:23:51.234Z",
"Munkahely": {
"Id": 34,
"Nev": "Cég 2"
}
},
...
I get this error: TypeError: Cannot read property 'Nev' of undefined
The problem occures because the JSON response is not consistent:
row.Jogosultsagok[1] is not always defined as the nested Array sometimes only contains one element.
You can fix the error by leaving the table cell empty in case the value is missing:
<template>
<tbody>
<tr v-for="row in get_rows()">
<td>{{row.Id}}</td>
<td>{{row.Nev}}</td>
<td>{{row.Jogosultsagok[0].Nev}}</td>
<td v-if="row.Jogosultsagok[1]">{{row.Jogosultsagok[1].Nev}}</td>
<td v-else></td>
</tr>
</tbody>
</template>
Related
I am working with some data collected from a Json file. With a react fetch function I have created an object called "category_evolution". I am trying to use a map function to create a table with that object.
category_evolution =
[
{
"name": "01/02/2023",
"data": [
{
"id": 30,
"category": "Criptomoedas",
"category_total_brl": "12000.00",
"category_total_usd": "2400.00",
"date": "01/02/2023"
},
{
"id": 28,
"category": "REITs",
"category_total_brl": "16000.00",
"category_total_usd": "3200.00",
"date": "01/02/2023"
},
{
"id": 26,
"category": "Stocks",
"category_total_brl": "20100.00",
"category_total_usd": "4020.00",
"date": "01/02/2023"
}
]
},
{
"name": "01/01/2023",
"data": [
{
"id": 29,
"category": "Criptomoedas",
"category_total_brl": "10000.00",
"category_total_usd": "2000.00",
"date": "01/01/2023"
},
{
"id": 27,
"category": "REITs",
"category_total_brl": "15000.00",
"category_total_usd": "3000.00",
"date": "01/01/2023"
},
{
"id": 25,
"category": "Stocks",
"category_total_brl": "20000.00",
"category_total_usd": "4000.00",
"date": "01/01/2023"
}
]
}
]
Here is my table code:
<table className="table">
<thead>
<tr>
<th scope="col">Categoria</th>
{category_evolution.map(({ name }) => (
<th scope="col" key={name}>{name}</th>
))}
</tr>
</thead>
<tbody>
{category_evolution.map(({ data }) =>
data.map(({ id, category, category_total_brl }) => (
<tr key={id}>
<td>{category}</td>
<td>{category_total_brl}</td>
</tr>
))
)}
</tbody>
</table>
The output of this code is a table like that
Categoria 01/02/2023 01/01/2023
Criptomoedas 12000.00
REITs 16000.00
Stocks 20100.00
Criptomoedas 10000.00
REITs 15000.00
Stocks 20000.00
But I would like to achieve an output like this:
Categoria 01/02/2023 01/01/2023
Criptomoedas 12000.00 10000.00
REITs 16000.00 15000.00
Stocks 20100.00 20000.00
I appreciate any help you can provide.
One way to do it is to combine all the data into a single array and then to map that array into an object where keys are the categories and the values are combined data for each "date":
const combinedData = category_evolution.reduce((acc, cur) => {
return [...acc, ...cur.data];
}, []);
const categoryMap = combinedData.reduce((acc, cur) => {
if(!acc[cur.category]) {
acc[cur.category] = [cur];
return acc;
}
acc[cur.category].push(cur);
return acc;
}, {});
And then the JSX:
<table className="table">
<thead>
<tr>
<th scope="col">Categoria</th>
{category_evolution.map(({ name }) => (
<th scope="col" key={name}>{name}</th>
))}
</tr>
</thead>
<tbody>
{Object.keys(categoryMap).map(category => {
return (
<tr key={category}>
<th>{category}</th>
<td>{categoryMap[category][0].category_total_brl}</td>
<td>{categoryMap[category][1].category_total_brl}</td>
</tr>
)
})}
</tbody>
</table>
Combined data provided from #o4ohel
const combinedData = category_evolution.reduce((acc, cur) => {
return [...acc, ...cur.data];
}, []);
const categoryMap = combinedData.reduce((acc, cur) => {
if(!acc[cur.category]) {
acc[cur.category] = [cur];
return acc;
}
acc[cur.category].push(cur);
return acc;
}, {});
Here's an updated version of the code provided by #o4ohel that can be improved for readability and maintainability:
<table className="table">
<thead>
<tr>
<th scope="col">Categoria</th>
{category_evolution.map(({ name }) => (
<th scope="col" key={name}>{name}</th>
))}
</tr>
</thead>
<tbody>
{Object.entries(categoryMap).map(([category, values]) => (
<tr key={category}>
<th>{category}</th>
{values.map(({ id, category_total_brl }) => (
<td key={id}>{category_total_brl}</td>
))}
</tr>
))}
</tbody>
</table>
A nested map is used to iterate over the values for each category, which allows for greater flexibility in case there are more or less values for each category in the future.
I have json object like this:
{
"cartId": 1,
"cartName": "Cart",
"CartItems": [
{
"productId": 1,
"product": {
"productId": 1,
"productName": "milk",
"price": 3.0,
"categoryId": 1,
},
"price": 3.0,
"quantity": 4,
"subTotal": 12.0
},
{
"productId": 2,
"product": {
"productId": 2,
"productName": "oranges",
"price": 3.0,
"categoryId": 5,
},
"price": 3.0,
"quantity": 6,
"subTotal": 18.0
}
],
"grandTotal": 30.0
}
this is my service:
getCart(): Observable<Cart[]> {
return this.http.get<Cart[]>(this.myAppUrl + this.myApiUrl)
.pipe(
retry(1)
);
}
this is my component:
cart$: Observable<Cart[]>;
constructor(private cart_Service: CartService,private http: HttpClient) {
}
ngOnInit() {
this.loadCart();
}
loadCart() {
this.cart$ = this.cart_Service.getCart();
}
I want to catch grandTotal like this in cart.component.html file:
<p *ngIf="!(cart$ | async)"><em></em></p>
<table class="table table-sm table-hover" >
<thead>
<tr>
<th> Grand Total</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let i of (cart$ | async)">
<td>{{ i.grandTotal }}</td>
</tr>
</tbody>
but I get error saying that " NgFor only supports binding to Iterables such as Arrays."
I tried different solutions to convert my json object to typescript array but none of them were helpful.
Can someone please help me to catch grandTotal and show it with html in my web api. I think we should have array to be able to get that grandTotal.
You can try either this
return this.http.get<Cart[]>(this.myAppUrl + this.myApiUrl)
.pipe(
map(response => response as unknows as Cart[])
retry(1)
);
OR
map the response as Cart[]
I finally could solve this. This is my service
getCart(): Observable<Cart[]> {
return this.http.get<Cart[]>(this.myAppUrl + this.myApiUrl);
}
this is my component:
my_data: any;
public loadCart() {
this.cart_Service.getCart().subscribe((data: Cart[]) => this.my_data = data);
}
this is my HTML:
<div>
<p> Grand Total : {{ my_data.grandTotal }} </p>
</div>
I have following problem: I try to get the values of "place" with ngfor.
Following i use:
.html
<ng-container *ngFor="let se of List"
Following Json:
.json
"place": [
{
"id": 1,
"name": "Ort",
"number": "Nummer",
"type": "Art",
"height": 20,
"width": 42,
"lagerin": [
{
"id": 1,
"secnname": "Regal ",
"secnnumber": "R1",
"sectype": {
"sectypename": "Big ",
"ro": 5,
"co": 2,
"secheight": 20,
"secwidth": 6,
"secdepth": 1,
"sectco": 1
}
},
{
"id": 2,
"secnname": "Reg 2 ",
"secnnumber": "R2",
"sectype": {
"sectypename": "Small",
"ro": 3,
"co": 3,
"secheight": 25,
"secwidth": 4,
"secdepth": 2,
"sectco": 2
}
}
]
}
]
I get the error above. So my idea is to get the attributes in "place" to use them in my code.
It was working fine, before i add "lagerin". But i need this one in "place".
.ts
ngOnInit() {
this.route.queryParams
.subscribe(params => {
this.id = params.id;
});
if (this.id) {
this.service.gelager(this.id).subscribe(data => {
if (data) {
this.List= data;
} else {
console.log('No lager available');
}
});
}
}
If your getLager method returns the Json you showed us then you should have
this.list = data.place
And your local variables should not start with a capital letter, it is just a convention
I want to display nested JSON data in a react-table.
I tried it like this:
render() {
const columns = [{
//Not Displaying
Header: 'Owner ID',
id: 'ownerid',
accessor: '_links.customer.href.ownerid', // <- i think this is wrong
Cell: this.renderEditable
},
{
//Displaying
Header: 'Price',
accessor: 'price',
Cell: this.renderEditable
}, {
The data i am getting back and have bound to the table is structured as follows:
[
{
"id": 1,
"date": "20.07.2019",
"price": 3.2,
"customer": {
"ownerid": 1,
"firstname": "John",
"lastname": "Johnson"
}
}
]
Here i am using the columns array:
import ReactTable from "react-table";
<ReactTable data={this.state.offers} columns={columns}
filterable={true} pageSize={10}/>
Binding the data:
fetchOffers = () => {
const token = sessionStorage.getItem("jwt");
fetch(SERVER_URL + 'api/offers',
{
headers : {'Authorization':token}
})
.then((response) => response.json())
.then((responsteData) => {
this.setState({
offers: responsteData._embedded.offers,
});
console.log(this.state);
})
.catch(err=> console.error(err));
}
The data i am using after binding:
Check the Accessors documentation. It has several examples for complex data structure.
I don't see _links or href in your sample data. So I think that you need just:
accessor: 'customer.ownerid'
The data structure from the console screenshot doesn't match your sample data. And it doesn't seem to contain ownerid. Try accessor: '_links.customer.href' to check whether it outputs anything to the table.
I figured it out.
I called the endpoint "localhost:8080/api/offers" and saved the following response:
"offers": [
{
"date": "20.07.2019",
"price": 3.2,
"_links": {
"self": {
"href": "http://localhost:8080/api/offers/1"
},
"offer": {
"href": "http://localhost:8080/api/offers/1"
},
"customer": {
"href": "http://localhost:8080/api/offers/1/customer"
}
}
}
]
there is no customer object
But when i call "localhost:8080/offers" i get:
[
{
"id": 1,
"date": "20.07.2019",
"price": 3.2,
"customer": {
"ownerid": 1,
"firstname": "John",
"lastname": "Johnson"
}
}
]
i changed the URI in my project and now the number is displaying.
I still don't know why i get data from "../api/offers" but i will research.
I had to access a nested object and display it with some styling, and this ended up working for me:
(Note: I was using typescript, so some of the typing might not be necessary)
{
Header: 'Thing To Display',
accessor: 'nested.thing.to.display',
Cell: ({ row }: { row: Row }) => (
<p>{row.values['nested.thing.to.display']}</p>
),
}
I'm trying to display three data tables as shown on this page with the variant of getting the data from my database, as shown here.
I first tested the page with the static data (from arrays.txt - first link) and it worked fine. However I'm now struggling with the MYSQL data and the JSON.
An info message showing "Processing..." shows up but the tables stay empty.
My Javascript:
$(document).ready(function(){
$('a[data-toggle="tab"]').on( 'shown.bs.tab', function (e) {
$.fn.dataTable.tables( {visible: true, api: true} ).columns.adjust();
} );
$('table.table').DataTable( {
"processing": true,
"serverSide": true,
"ajax": {
"dataSrc": "Data", // Tried adding this but didn't help
"url": "/hireStaffController/getDataTable",
"type": "POST"
},
"columns": [
{ "data": "id_staff" },
{ "data": "name_english" },
{ "data": "name_french" },
{ "data": "position" },
{ "data": "efficiency" },
{ "data": "salary" }
]
} );
}
My controller:
public function getDataTable(){
$data = $this->staffModel->get_all_staff_DB();
echo json_encode($data);
}
My Model:
public function get_all_staff_DB(){
$query = $this->db
->select('*')
->from('game_staff')
->get();
return $query->result();
}
The JSON Response from Firebug seems correct:
[{
"id_staff": "1",
"name_english": "Ski patrol 1",
"name_french": "Pisteur secouriste 1",
"position": "skipatrol",
"efficiency": "50",
"salary": "1500"
}, {
"id_staff": "10",
"name_english": "Bus driver 2",
"name_french": "Chauffeur de bus 2",
"position": "driver",
"efficiency": "55",
"salary": "1380"
}]
Firebug throws this error:
TypeError: c is undefined
...iRecordsDisplay=parseInt(f,10);d=0;for(e=c.length;d<e;d++)N(a,c[d]);a.aiDisplay=...
^
So I've tried to add "dataSrc": "Data", in the Ajax, as described here but no luck, same error. WHat is this Data? I tried with a small "d" as well.
Can you see what is wrong?
My HTML code:
<div class="tab-pane active" id="tab-table1">
<table id="myTable1" class="table table-striped table-bordered" cellspacing="0" width="100%">
<thead>
<tr>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Extn.</th>
<th>Start date</th>
<th>Salary</th>
</tr>
</thead>
</table>
</div>
<div class="tab-pane" id="tab-table2">
<table id="myTable2" class="table table-striped table-bordered" cellspacing="0" width="100%">
//same ...
</table>
</div>
try including "Data" as key to the echoed data:
public function getDataTable(){
$data = $this->staffModel->get_all_staff_DB();
echo json_encode(array('Data' => $data));
}
When you specify dataSrc as "Data", datatables looks for a "Data" property in the json returned by the ajax call, and uses that property as source for the table.
I hope the HTML table with is present there.
Try using ID instead of class.
Everything else you have done looks fine.
$('#ID').DataTable( {
"processing": true,
"serverSide": true,
"ajax": {
"url": "/hireStaffController/getDataTable",
"type": "POST"
},
"columns": [
{ "data": "id_staff" },
{ "data": "name_english" },
{ "data": "name_french" },
{ "data": "position" },
{ "data": "efficiency" },
{ "data": "salary" }
]
} );