table rows and data won't show in JSX table in React document - html-table

I am trying to build a simple React app. I have a page with a table that I am currently trying to render with fake data. I can successfully navigate to and render the page, but when I do, only the header and none of my rows with data show up. Here is my code right now:
import React from 'react';
const Campus = (props) => {
const campus = {
name: 'Terra',
students: ['katie', 'lara'],
instructors: ['joe', 'bob']
}
return (
<table className='table'>
<thead>
<tr>
<th>Students</th>
</tr>
</thead>
<tbody>
{ console.log("students ", campus.students) }
{ campus.students && campus.students.map((student, idx) => {
<tr key={idx} >
<td>
{console.log('student is ', student)}
{student}
</td>
</tr>
})
}
</tbody>
</table>
);
}
export default Campus;
I can console.log the students' name inside the map, but when the page loads, nothing but the header shows up. It's very possible I'm missing something very obvious; I'm new to this.

change
<tr key={idx} >
for
return <tr key={idx} >

Related

Failed returning data from array

i have a problem which that i cannot see the data inside array that i have pushed the data inside .then from axios
Here are the sample code
Axios from vue.js
export default {
name: 'facts',
data(){
const test = [{id: 'test',name: 'test'}]
const response = [];
const factsData = () => {
axios.get('http://localhost:3000').then(x=>response.push(x.data))
}
factsData();
console.log(response)
return{
test,
response
};
}
};
When i tried to console.log the output data inside the promise(.then) it worked well and display the data that i expected like this
and this is what happen when i tried to push the data from axios to response and show the output data in console.log with my current code above
when i tried to access it (console.log(response[0]), it shows undefined in console.log.
But strangely, when i back to my previous code to not to tried to access the data and i expand the array in console browser, it shows data that i expected which mean i couldn't access it.
The main purpose is i want to dipsplay the data to be rendered in table using v-for
<template>
<div class="about">
<center>
<table>
<thead>
<tr>
<th></th>
<th>ID</th>
<th>Username</th>
</tr>
</thead>
<tbody>
<tr v-for="(user,index) in test" :key="user.id">
<td>{{index + 1}}</td>
<td>{{user.id}}</td>
<td>{{user.name}}</td>
</tr>
</tbody>
</table>
</center>
</div>
</template>
Please tell me what i'm missing. Thank you.
P.S : I'm new to this vue js
your code structure is not correct. use this code:
export default {
name: 'ProfilePage',
data() {
return {
response: []
}
},
created () {
this.getData();
},
methods: {
getData() {
axios.get('http://localhost:3000').then(x => this.response = x.data);
}
}
}

How can I get a result from a POST request into a v-for?

I have something like this:
<table class="table">
<tbody>
<tr v-for="(option, index) in Weapons">
<td>Primary</td>
<td>[[ getWeaponType(option.WeaponType) ]]</td>
</tr>
</tbody>
</table>
In my Vue object, in methods, I have this:
getWeaponType: function(weaponTypeNumber){
axios.get('/path/to/api')
.then(response => {
return response.data
})
}
I send an ID and it returns the name for that ID. But I need for it to show in my table whose rows are being generated by the v-for. This isn't working since it is a Promise and the values are not showing. Is there any way I can achieve getting that value to show in the table? I didn't want to do it server side so I'm trying to see if I have any options before I do that.
May I suggest an alternative method?
data() {
return {
weaponsMappedWithWeaponTypes: [];
}
}
mounted() { // I am assuming the weapons array is populated when the component is mounted
Promise.all(this.weapons.map(weapon => {
return axios.get(`/path/to/api...${weapon.weaponType}`)
.then(response => {
return {
weapon,
weaponType: response.data
}
})
).then((values) => {
this.weaponsMappedWithWeaponTypes = values
})
}
computed: {
weaponsAndTheirWeaponTypes: function () {
return this.weaponsMappedWithWeaponTypes
}
}
And then in your template
<table class="table">
<tbody>
<tr v-for="(option, index) in weaponsAndTheirWeaponTypes">
<td>Primary</td>
<td>option.weaponType</td>
</tr>
</tbody>
</table>

React, TSX Parsing error: Expression expected

Below is REACT code for details page
Ticket is a primary object, and what i want to do is when downloading add the ticket name as .pdf filename.
So i need a solution to pass the concrete ticket name to the handleDownload function
In the render section there are no problem declaring ticket.ticketName etc. But with onClick the problem arises.
type TicketProps =
TicketStore.TicketState &
typeof TicketStore.actionCreators &
RouteComponentProps<{ticketId: string}>;
class Ticket extends React.PureComponent<TicketProps> {
public componentDidMount() {
this.ensureDataFetched();
}
private ensureDataFetched(){
this.props.requestTicket(+this.props.match.params.ticketId);
}
handleDownload = () =>{
Axios.get(`${apiUrl}/api/tickets/download/${this.props.match.params.ticketId}`,{responseType: 'arraybuffer',
headers: { "Content-Type": 'application/pdf' }
}).then((response) => {
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', "test"+.pdf");
document.body.appendChild(link);
link.click();
});
}
public render() {
let ticket = this.props.ticket;
if(this.props.isLoading){
return <span>Laen andmeid...</span>;
}
if (ticket === undefined) {
return <h1>Piletit ei leitud</h1>;
}
let name = ticket.ticketName
return (
<React.Fragment>
<h3>Üritus: {ticket.ticketName}</h3>
<Table striped hover size="sm">
<tbody>
<tr>
<td className="details">Asukoht:</td>
<td>{ticket.eventLocation}</td>
</tr>
<tr>
<td className="details">Kuupäev:</td>
<td>{ticket.eventDate}</td>
</tr>
<tr>
<td className="details">Lisainfo:</td>
<td>{ticket.extraInfo}</td>
</tr>
<tr>
<td className="details">Pilet:</td>
<td>{ticket.pdfTicket}</td>
</tr>
</tbody>
</Table>
<Button onClick={this.handleDownload}>Lae alla</Button>
<Popup trigger={<button className="btn btn-primary">Show location on map</button>} position="bottom left">
<div><Maps aadress={ticket.eventLocation}></Maps>></div>
</Popup>
<Link to='../tickets'>
<Button color='primary' onClick={()=>{}}>
Tagasi
</Button>
</Link>
<br></br>
</React.Fragment>
);
}
}
export default connect(
(state: ApplicationState) => state.ticket,
TicketStore.actionCreators
)(Ticket as any);
I am getting parsing error after ticket?
Any thoughts?
Thanks
Use the following code without the question marks:
<Button onClick={()=>{this.handleDownload(ticket.id,ticket.ticketName)}}>Lae alla</Button>
The solution was to add
if(this.props.ticket===undefined){
return //something;
}
Before using the object.

Vuejs and datatables: table empty when using v-for to fill data

I'm trying to fill a datatable using vuejs v-for directive and ajax to get the data but the table is always showing "No data available in table" even though there are some data shown and also in the bottom says "Showing 0 to 0 of 0 entries". I guess this is because vuejs is reactive and the table can't recognize the changes maybe?
I've been searching and trying for a while but with no solution found..
thanks a lot! :)
here's the template:
<table id="suppliersTable" class="table table-hover table-nomargin table-bordered dataTable">
<thead>
<tr>
<th>...</th>
...
</tr>
</thead>
<tbody>
<tr v-for="supplier in suppliers">
<td>{{ supplier.Supplier_ID }}</td>
<td>...</td>
...
</tr>
</tbody>
</table>
and the vue and ajax:
<script>
export default {
data() {
return {
suppliers: [],
}
},
methods: {
fetchSuppliers() {
this.$http.get('http://localhost/curemodules/public/suppliers/list')
.then(response => {
this.suppliers = JSON.parse(response.bodyText).data;
});
}
},
created() {
this.fetchSuppliers();
},
}
Once initialized, DataTables does not automatically reparse the DOM. Here's a relevant FAQ:
Q. I append a row to the table using DOM/jQuery, but it is removed on redraw.
A. The issue here is that DataTables doesn't know about your manipulation of the DOM structure - i.e. it doesn't know that you've added a new row, and when it does a redraw it will remove the unknown row. To add, edit or delete information from a DataTable you must use the DataTables API (specifically the row.add(), row().data() and row().remove() methods to add, edit and delete rows.
However, you can call table.destroy() to destroy the current instance before reinitializing it. The key is to delay the reinitialization until $nextTick() so that Vue can flush the DOM of the old DataTables. This is best done from a watcher on suppliers so that the DataTables reinitialization is done automatically when the variable is updated in fetchSuppliers().
mounted() {
this.dt = $(this.$refs.suppliersTable).DataTable();
this.fetchSuppliers();
},
watch: {
suppliers(val) {
this.dt.destroy();
this.$nextTick(() => {
this.dt = $(this.$refs.suppliersTable).DataTable()
});
}
},
demo
I know this is a bit late answer but I just encountered this problem just today and my only solution for this issue is using setTimeout function.After fetching data using axios I set a bit of delay then init the data-table. With this work around v-for works fine.
See below for my code.
GetDepartmentList(){
axios.get('department')
.then((response) => {
this.departmentList = response.data;
// this.dataTable.rows.add(response.data).draw();
setTimeout(() => $('#department-data-table').DataTable(), 1000);
})
.catch((error) => {
if (error.response.status == 401) {
alert('User session has expired. Please login again.');
location.replace("/login");
}
});
},
Also you can use .rows.add() function if you want to draw row data in the table without using v-for of vue. Refer to this doc.
You can using Axios in Vuejs, you try see the following above:
<template>
<div class="danhsach">
<h2>{{title}}</h2>
<table class="table">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Password</th>
<th>Age</th>
</tr>
</thead>
<tbody>
<tr v-for='data in datas'>
<td>{{data.id}}</td>
<td>{{data.name}}</td>
<td>{{data.password}}</td>
<td>{{data.age}}</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
export default{
data(){
return {
title:"Tile Lists",
datas:[]
}
},
created:function(){
this.danhsach_user();
},
methods:{
danhsach_user(){
this.axios.get('https://599f807effe73c0011b9fcc5.mockapi.io/api/user').then((response)=>{
this.datas=response.data;
});
}
}
}
</script>

Building a simple table component

I would like to build two components, one for the table and one for each row.
Coding for the table looks like that:
#Component({
tag: 'wb-overview-table',
})
export class WorkbookOverviewTable {
items: Array<any>;
constructor() {
this.items = [ { id: 1, name: "asd" }, { id: 2, name: "qwes" } ];
}
render() {
return (
<table>
{this.items.map(item => {
return (
<wb-overview-table-row item={item}></wb-overview-table-row>
);
})}
</table>
);
}
}
Coding for row looks like that:
#Component({
tag: 'wb-overview-table-row',
})
export class WorkbookOverviewTableRow {
#Prop() item: any;
render() {
return (
<tr>
<td>{this.item.id}</td>
<td>{this.item.name}</td>
</tr>
);
}
}
The rendered html looks like that:
<wb-overview-table class="hydrated">
<table>
<wb-overview-table-row class="hydrated">
<tr>
<td>1</td>
<td>asd</td>
</tr>
</wb-overview-table-row>
<wb-overview-table-row class="hydrated">
<tr>
<td>2</td>
<td>qwes</td>
</tr>
</wb-overview-table-row>
</table>
</wb-overview-table>
Problem is, that the structure of the table isn't correct. And I understand why it get's rendered like that. But I just don't know how to render the table correctly, so that table-tag will have the tr-tags as child elements.
What is the correct way of building two components, one for the table and one for the rows?
Thanks a lot!
HTML <table> elements don't allow for custom elements as children, which means you can't use a Stencil Web Component directly.
You can, however, use a Functional component as a child row, similar to React:
export const WorkbookOverviewTableRow = props =>
return (
<tr>
<td>{props.item.id}</td>
<td>{props.item.name}</td>
</tr>
);
}
}
And in your table component:
<table>
{this.items.map(item => {
return (
<WorkbookOverviewTableRow item={item} />
);
})}
</table>
);
These are Stencil components, but they don't get exported as Web Components, so you can only use them inside other Stencil Components.