React: table td is populating horizontally - html

I was working on this json data with react-table, it displays yet horizontally in a single <td></td>, your inputs are highly appreciated.
export const COLUMNS = [
{
Header: 'mId',
accessor: (row) => {return row.skus.map(sku => sku.mId); }
}]
Please note that I can access the data and print but it looks weird.
Expected Output:
<td>sku2620222 </td>
<td>sku2620220</td>
<td>sku2680407 </td>
<td>sku2680408 </td>
<td>sku10980349 </td>
<td>sku2680406</td>
Real output:
<td> sku2620222sku2620220sku2680407sku2680408sku2680405sku10980349sku2680406</td>
Basically I want it to display in every row. Thanks a lot

Each item you map through needs to be in its own row. Then you can add as many table downs as you need. That way each time you map through it, it will render a new table row. Here is an extremely simple table you can follow.
export default function App() {
let data = [
{sku: "sku2620222"},
{sku: "sku2620220"},
{sku: "sku2680407"},
{sku: "sku2620222"},
{sku: "sku2680408"},
]
let tabledata = data.map(i => {
return (
<tr>
<td>
{i.sku}
</td>
</tr>
)
})
return (
<>
<table>
<thead>
<tr>
<th>
SKU
</th>
</tr>
</thead>
<tbody>
{tabledata}
</tbody>
</table>
</>
)
}

Related

Filling a table with JSON data

I am taking mmy first steps in Angular and was about to try populating a table with data stored in a JSON file. Facing a bit of an odd/unexpected situation there as the table doesn't look exactly how I expected it to look. First things first.
Table code:
<table class="table table-sm table-bordered">
<thead>
<tr>
<th>Transfers</th>
<th>Tools</th>
</tr>
</thead>
<tbody>
<tr *ngFor = "let data of linksArray">
<td>{{ data.Transfers}}</td>
<td>{{ data.Tools}}</td>
</tr>
</tbody>
</table>
What I would like to achieve is that the columns Transfers and Tools get filled with data that uses the corresponding keywords in my JSON file. And here it is
[{"Type":"Transfers","Name":"1","Hyperlink":"#"}, {"Type":"Transfers","Name":"2","Hyperlink":"#"},
{"Type":"Tools","Name":"1","Hyperlink":"#"}, {"Type":"Tools","Name":"2","Hyperlink":"#"}]
The array gets loaded by using this in my .ts file
this.http.get('../../assets/templatefiles/links.json').subscribe(data => {this.linksArray = data as
any [];
console.log(this.linksArray);
},
(err: HttpErrorResponse) => {
console.log (err.message);
}
);
So far all looks good, I see the array popping up in console, but then look at the table and am confused
I would have expected the entries in the 2nd column to start in the first cell. Instead they start in the 3rd? What am I missing here? Been marveling for quite a while now :)
https://stackblitz.com/edit/angular-ivy-hvcyfq
To get this
Transfers Tools
1 10
2 20
You want code roughly like this
<hello name="{{ name }}"></hello>
<table class="table table-sm table-bordered">
<thead>
<tr>
<th>Transfers</th>
<th>Tools</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let data of linksArray">
<td>{{data.Transfers.Name}}</td>
<td>{{data.Tools.Name}}</td>
</tr>
</tbody>
</table>
And, this is the main bit, json roughly like this
linksArray = [
{
Transfers: {
Name:"1",
Hyperlink:"#"
},
Tools: {
Name:"10",
Hyperlink:"#"
}
},
{
Transfers: {
Name:"2",
Hyperlink:"#"
},
Tools: {
Name:"20",
Hyperlink:"#"
}
},
Your existing json looks like this, where the '{' represents one row
[
{
"Type":"Transfers",
"Name":"1",
"Hyperlink":"#"
},
{
"Type":"Transfers",
"Name":"2",
"Hyperlink":"#"
},
{
"Type":"Tools",
"Name":"1",
"Hyperlink":"#"
},
{
"Type":"Tools",
"Name":"2",
"Hyperlink":"#"
}
]

Dynamic <table> not rendering data

I'm trying to create a dynamic table that renders data inserted based on a format of
{headers: ["header1", "header2"], rows: [["data1", "data2"], ["moredata", "wowoso muchdata"]]}
Rows is just an array of arrays and each array is a row in the table.
I pass this data into a React component which renders the table. The code is the following:
export default class StandardTable extends React.Component<Props, State>{
constructor(props){
super(props);
this.state = {
tableData: this.props.data
}
}
render(){
return(
<div>
<table id="StandardTable">
<tbody>
{this.state.tableData.headers.map(function(header){
<th>{header}</th>
})}
</tbody>
<tbody>
{this.state.tableData.rows.map(function(row){
<tr>
{row.map(function(rowItem){
<td>{rowItem}</td>
})}
</tr>
})}
</tbody>
</table>
<style jsx>
{`
#StandardTable{
border: 1px solid black;
}`}
</style>
</div>
);
}
}
I am able to console log the data object and all the data is there. It's also iterating through the data in the map functions as I can check in console, but unfortunately the table shows up blank in practice.
can you try this, no need to return, you can use arrow function
<table id="StandardTable">
<tbody>
{this.state.tableData.headers.map((header) => (
<th>{header}</th>
))}
</tbody>
<tbody>
{this.state.tableData.rows.map((row)=>(
<tr>
{row.map((rowItem)=>(
<td>{rowItem}</td>
))}
</tr>
))}
</tbody>
</table>
Hope it will work.
It's because you forgot the return. Just do this in your map functions:
{this.state.tableData.headers.map(function(header){
return <th>{header}</th>
})}
There is no return in map
this.state.tableData.rows.map(function(row){
return( <tr>
{row.map(function(rowItem){
return <td>{rowItem}</td>
})}
</tr>)
})

How to map specific items within react when using json object

I have a json object that I'm trying to map into a table within a react component. I'm having difficulty accessing the 'title' and the 'tooltip' from within the json object. The console log successfully shows me the entire the json object, but
this.props.selectedProducts.products.title
Which I thought would map to the 'title' part of the json data simply doesn't work. Can anyone tell me what I'm doing wrong & possibly how to correct it? Thanks in advance!
JSON:
selectedProducts: [
{
“start”: “Tue Jun 19 16:55:40 BST 2018”,
“products”: [
{
“title”: “SL Primary - Alaska (Westlaw PRO™)“,
“price”: “”
},
{
“title”: “SL Ninth Circuit Primary Law (Westlaw PRO™)“,
“price”: “”
}
]
}
],
React:
renderProducts() {
const selected = this.props.selectedProducts;
return this.props.selectedProducts.map((selected, i) => {
return (
<tr className="product-cells" key={i}>
<td> {selected.title} </td>
<td> {selected.price}</td>
</tr>
);
});
}
selectedProducts is an array, so you have to access the first object in the array, and map over products:
renderProducts() {
return this.props.selectedProducts[0].products.map((selected, i) => {
return (
<tr className="product-cells" key={i}>
<td> {selected.title} </td>
<td> {selected.price}</td>
</tr>
);
});
}
You should use first element of your selectedProducts array as answered before or use a second map if there will be more objects:
renderProducts() {
return (
this.props.selectedProducts.map(el =>
el.products.map(selected =>
<tr className="product-cells" key={selected.title}>
<td> {selected.title} </td>
<td> {selected.price}</td>
</tr>)
)
)
}
Do not use indexes as your keys. There could be some problems if you do so.

Is it possible to dynamically populate Angular 2 Material Tabs with a For Loop Subscribe?

I need to populate a dynamic amount of Tabs on an Angular 2 site using a For Loop that is using a subscribe to get data from a database service and I am wondering if it is even possible.
My data set is broken down by Classes: A, B and C and they each have a Sub-Class of 1 and 2. So I would like to have my results dynamically create 3 tabs (Tab A, Tab B, and Tab C). So far I have this working.
I then need each of these tabs to then display the data of their Sub-Classes. As of now the loop runs the 3 times and provides the data needed but every page just shows data for Class C as it was the last one to run and the model is updated with all of its data.
Below is what I have thus far.
classdata.component.html
<mat-tab-group>
<mat-tab *ngFor="let classresult of classresults;" label="Class -{{classresult.Class_Name}}">
<table class ="responstable">
<thead>
<tr>
<th>Sub-Class Name</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let subclassresult of subclassresults;">
<td>{{subclassresult.Sub_Class_Name}} </td>
<td>{{subclassresult.Value}} </td>
</tr>
</tbody>
</table>
</mat-tab>
</mat-tab-group>
classdata.component.ts
// Populate Class Level Data
this.databaseService.getClass()
.subscribe(classresults => this.classresults = classresults,
error => console.log('ERROR!'),
// Populate Sub-Class Level Data
() => { for (const classresult of this.classresults) {
this.selectedClassId = classresult.Class_ID;
console.log(this.selectedClassId);
this.databaseService.getSubClass(this.selectedClassId)
.subscribe(subclassresults => this.subclassresults = subclassresults);
}
}
);
database.service.ts
getClass(): Observable<ClassResult[]> {
const url = 'http://localhost:3000/c';
const data = ({
});
return this._http.post(url, data)
.pipe(
map((res) => {
console.log(res);
return <ClassResult[]> res;
})
);
}
getSubClass(Class_ID): Observable<SubClassResult[]> {
const url = 'http://localhost:3000/sc';
const data = ({
classid: Class_ID
});
return this._http.post(url, data)
.pipe(
map((res) => {
console.log(res);
return <SubClassResult[]> res;
})
);
}
You are fetching each Subclass for every parentClass but you are reassigning each result to the class variable this.subclassresults. Basically you are overwriting each previous result with the current result. Thats why every page just shows data for Class C.
There are many different solutions how you can solve this problem.
On solution could be you are using forkJoin Observable and save the result of your parentClass with their subClasses in their own object:
this.databaseService.getClass().pipe(
switchMap(classResults => {
const subClassRequests = classResults.map(
classResult => this.dabaseService
.getSubClass(classResult)
.pipe(map(subClassResults => {classResult, subClassResults}))
)
return forkJoin(subClassRequests)
})
).subscribe(results => this.results = results);
results holds your data as an array.
And in your template use it like this:
<mat-tab-group>
<mat-tab *ngFor="let result of results;" label="Class -{{result.classresult.Class_Name}}">
<table class ="responstable">
<thead>
<tr>
<th>Sub-Class Name</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let subclassresult of result.subclassresults;">
<td>{{subclassresult.Sub_Class_Name}} </td>
<td>{{subclassresult.Value}} </td>
</tr>
</tbody>
</table>
</mat-tab>
</mat-tab-group>
I implemented a small working Demo: StackBlitz Demo

Header and data elements in same row using set_template in CodeIgniter

I am using the HTML Table Class of CodeIgniter, and attempting to create a table template. The example given in the documentation is the following:
$tmpl = array (
'table_open' => '<table border="0" cellpadding="4" cellspacing="0">',
'heading_row_start' => '<tr>',
'heading_row_end' => '</tr>',
'heading_cell_start' => '<th>',
'heading_cell_end' => '</th>',
'row_start' => '<tr>',
'row_end' => '</tr>',
'cell_start' => '<td>',
'cell_end' => '</td>',
'row_alt_start' => '<tr>',
'row_alt_end' => '</tr>',
'cell_alt_start' => '<td>',
'cell_alt_end' => '</td>',
'table_close' => '</table>'
);
$this->table->set_template($tmpl);
When I apply this template to my query, this is the resulting HTML:
<table data-hide-table="false" data-orientation="vertical" class="chart">
<thead>
<tr>
<th></th><th>Rate per SF</th></tr>
</thead>
<tbody>
<tr>
<td>2008</td><td>48</td></tr>
<tr>
<td>2009</td><td>32</td></tr>
<tr>
<td>2010</td><td>32</td></tr>
<tr>
<td>2011</td><td>32</td></tr>
<tr>
<td>2012</td><td>40</td></tr>
<tr>
<td>2013</td><td>41</td></tr>
</tbody>
</table>
The problem with this example is that each row contains two data elements (<td></td><td></td>), instead of one header element and one data element (<th></th><td></td>).
How can I change the template so that my resulting table will have one header element and one data element (<th></th><td></td>) on each row like this:
<table data-hide-table="false" data-orientation="vertical" class="chart">
<thead>
<tr>
<th></th><th>Rate per SF</th></tr>
</thead>
<tbody>
<tr>
<th>2008</th><td>48</td></tr>
<tr>
<th>2009</th><td>32</td></tr>
<tr>
<th>2010</th><td>32</td></tr>
<tr>
<th>2011</th><td>32</td></tr>
<tr>
<th>2012</th><td>40</td></tr>
<tr>
<th>2013</th><td>41</td></tr>
</tbody>
</table>
Thanks.
The answer is no you can't change template like this but yes you can somewhere achieve this kind of functionality
If you see the http://ellislab.com/codeigniter/user-guide/libraries/table.html there is a option to add a callable function so I suggest you are creating a table make some flag if you are using that table is generating than create a helper function and add that to the table function than before generating table set a flag to determine the first cell may be using cookie. Than from helper for every 1, 3....(2n+1) add some custom html tag or style. Than after generating the table remove all the flags.