Building a simple table component - tsx

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.

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>

I have an issue with a vue component not rendering data

I am retrieving data in two steps. All data can be viewed in the Vue dev tools but data retrieved in the second step is not rendered.
My code is as follows:
data() {
return {
activeEmployees: {},
}
},
methods: {
loadEmployees() {
axios.get("/api/organizations/employees/" + this.$route.params.organizationId)
.then(({data}) => (
this.activeEmployees = data.active_employees
))
.then(() => (
this.getUserServices()
));
},
getUserServices() {
for (const element of this.activeEmployees) {
axios.get("/api/organizations/employees/services/" + element.id + "/" + this.$route.params.organizationId)
.then(response => Object.assign(element, response.data));
}
},
},
mounted() {
this.loadEmployees()
}
The data from the getUserServices method (user_services as per screenshot below) is not rendered yet it appears in the Vue dev tools.
Part of the template is as follows:
<tr :key="employee.id" v-for="employee in activeEmployees">
<td class="text-center">
<Avatar :userData="employee"/>
</td>
<td>
<div>{{employee.name}}</div>
<div class="small text-muted">
Registered: {{employee.created_at | formatDate}}
</div>
</td>
<td>
{{employee.user_services}}
</td>
</tr>
And a snapshot of the Vue dev tools is as follows:
The user_services is empty in the view yet available in the dev tools.
How can this be refactored to render all data?
You should use the $set method somewhere to make your data reactive. For example:
axios.get("/api/organizations/employees/services/" + element.id + "/" + this.$route.params.organizationId)
.then(response => {
Object.keys(response.data).forEach(key => this.$set(element, key, response.data[key])
})

Vuejs class doesn't update after ajax request

What I'm trying to do is to highlight a table row after the component has been created or mounted. The playingTrack value is being changed to the id of the current song but the class doesn't change.
The #click function works and changes the class to highlight but what I want is for it to happen when component is mounted taking its value from playingTrack variable.
<tr :class="{highlight:track.id == playingTrack}" #click="playingTrack = track.id" v-for="track in tracks">
<td class="align-middle">
{{track.title}} <br> <span style="color: grey;">{{track.artist}}</span>
</td>
</tr>
<script>
export default{
data(){
return{
tracks:{},
album:{},
playingTrack: undefined
}
},
beforeCreate(){
Event.$emit('requestCurrentTrack');
Event.$on('currentTrack', (data) => this.fetchAlbum(data));
},
methods:{
fetchAlbum(data){
axios.get('/api/album/'+this.id).then((response)=>{
if(data){
this.playingTrack = data.id;
}
this.tracks = response.data[0];
this.album = response.data[1][0];
});
}
}
}
</script>
You can use "Computed Property"
https://v2.vuejs.org/v2/guide/computed.html
Here is well-written documentation.

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

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