Angular2 #ngFor directive and table generation with Dart - dart

I have a single map
.dart
Map<String, String> name = {"title":"Countess","first":"Tommy","last":"Clarke","middle":"Kowan","suffix":"Junior"}
I would like to use angular2 #ngFor directive to construct a table looking like the one below
I can create the table in the conventional way using #ngFor with the Name column forming the table header row and the input column placed as the first table row. The graphic shown was done with the following code:
.html
<table class = "mdl-data-table mdl-js-data-tablemdl-shadow--4dp">
<thead>
<tr>
<th class = "mdl-data-table__cell--non-numeric">Name</th>
<th>Input</th>
</tr>
</thead>
<tbody>
<tr>
<td class = "mdl-data-table__cell--non-numeric">Title</td>
<td>{{name.title}}</td>
</tr>
<tr>
<td class = "mdl-data-table__cell--non-numeric">First</td>
<td>{{name.first}}</td>
</tr>
<tr>
<td class = "mdl-data-table__cell--non-numeric">Middle</td>
<td>{{name.middle}}</td>
</tr>
<tr>
<td class = "mdl-data-table__cell--non-numeric">Last</td>
<td>{{name.last}}</td>
</tr>
<tr>
<td class = "mdl-data-table__cell--non-numeric">Suffix</td>
<td>{{name.suffix}}</td>
</tr>
</tbody>
</table>
How can I crate the table in the graphic using #ngFor directive?
EDIT1 - CONSOLE ERROR WHEN RUN WITH FIRST SOLUTION
>EXCEPTION: Class '_CompactIterable' has no instance method '[]'.
NoSuchMethodError: method not found: '[]'
Receiver: Instance of '_CompactIterable'
Arguments: [null] in [{{names.keys[idx].slice(1,1).toUpperCase()}}{{names.keys[idx].slice(2)}} in NameComponent#148:52]
EXCEPTION: Class '_CompactIterable' has no instance method '[]'.
NoSuchMethodError: method not found: '[]'
Receiver: Instance of '_CompactIterable'
Arguments: [null] in [{{names.keys[idx].slice(1,1).toUpperCase()}}{{names.keys[idx].slice(2)}} in NameComponent#148:52]
(anonymous function)
ORIGINAL EXCEPTION: Class '_CompactIterable' has no instance method '[]'.
.dart (Dart's port of SnareChops answer below) | CORRECT ANSWER
Added a custom pipe to perform the capitalization
///Takes the first letter of [String] key in a [Map], capitalizes it and
///returns the key value as the capitallized word
#Pipe( name: 'capitalize' )
class CapitalizePipe extends PipeTransform {
dynamic transform( String value, List args ) {
StringBuffer buffer = new StringBuffer( );
List<String> list = value.split( '' );
if ( value != null ) {
for ( int i = 0; i < list.length; i++ ) {
if ( i == 0 ) {
buffer.write( list[i].toUpperCase( ) );
continue;
}
buffer.write( list[i] );
}
}
return buffer.toString( );
}
}
<tbody>
<tr *ngFor = "#name of names?.keys">
<td class = "mdl-data-table__cell--non-numeric">{{name | capitalize}}</td>
<td>
{{names[name]}}
</td>
</tr>
</tbody>

Iterate the keys of the Map, use those for the titles, and then you can use the key to access the value in the Map which gives you the value.
<tbody>
<tr *ngFor="#name of names?.keys">
<td class="mdl-data-table__cell--non-numeric">{{name}}</td>
<td>{{names[name]}}</td>
</tr>
</tbody>

Related

render: function - JSX failed to compilie with SyntaxError Unexpected token - Rails 5.1 Webpack Reactjs

I'm having an issue running a React component as I get a Syntax Error:
Failed to compile.
./app/javascript/RoastsJson/index.jsx Module build failed: SyntaxError: Unexpected token (6:10)
4 | class RoastsJson extends React.Component {
5 |
> 6 | render: function() {
| ^
7 | roasts = this.props.roasts.map( function(roast) {
8 | return (
9 | <tr key={roast.id}> # ./app/javascript/packs/roastsjson.jsx 3:0-36 # multi (webpack)-dev-server/client?http://localhost:3035 ./app/javascript/packs/roastsjson.jsx
just can't see why this would fail...my unrelated but I was having the same error when playing with files with const = url with the error pointing to the u in url.
app/javascript/RoatsJson/index.jsx
import React from 'react'
import ReactDom from 'react-dom'
class RoastsJson extends React.Component {
render: function() {
roasts = this.props.roasts.map( function(roast) {
return (
<tr key={roast.id}>
<td>{roast.name}</td>
</tr>
);
console.log(roast);
});
return (
<div>
<h1>Roasts</h1>
<div id="roasts">
<table>
<thead>
<tr>
<th>Name</th>
</tr>
</thead>
<tbody>
{roasts}
</tbody>
</table>
</div>
</div>
);
}
};
export default RoastsJson
I understand I could(should) remove function, such as:
render() {
roasts = this.props.roasts.map( function(roast)
but this then throws the following in the conosle:
unreachable code after return statement
Context
I'm trying to pull a Rails 5.1 resource called roasts into this react component. in my roasts_controller.rb:
def index
#roasts = Roast.all
render component: 'roatsjson', props: {roasts: #roasts}
end
The issue I could see is roasts which is not defined in your component. The better way to render array off elements is to use an array and push elements to it and print that.
Also start using arrow functions to avoid scope issues and function bindings.
Check below updated code and it should work.
class RoastsJson extends React.Component {
render() {
let roasts = []
this.props.roasts.map((roast) => {
roasts.push(
<tr key={roast.id}>
<td>{roast.name}</td>
</tr>
)
});
return (
<div>
<h1>Roasts</h1>
<div id="roasts">
<table>
<thead>
<tr>
<th>Name</th>
</tr>
</thead>
<tbody>
{roasts}
</tbody>
</table>
</div>
</div>
);
}
};
export default RoastsJson
It seems you pass an unexpected roasts props. You should try to use some checks on your props, using for example the prop-types library.
Also, it's generally a good practice to use pure fonction for a stateless component (see reactpatterns.com). Here one, un-tested :
import React from 'react';
import PropTypes from 'prop-types';
const RoastsJson = ({ roasts }) => (roasts && (<div>
<h1>Roasts</h1>
<div id="roasts">
<table>
<thead>
<th>Name</th>
</thead>
<tbody>
{
roasts.map(({id, name}) => <tr key={id}>
<td>{name}</td>
</tr>)
}
</tbody>
</table>
</div>
</div>));
RoastsJson.propTypes = {
roasts: PropTypes.array
};
export default RoastsJson;

MVC5 foreach loop change class based on SQL field

I'am learning MVC5 & Entity Framework 6, and have accomplished a connection to a SQL Database.
I need to change the class of the <tr> field based on the TicketStatus.StatusID result
For Example If the StatusID =1 then use:
<tr class="ticket even status-new priority-low">
if the statusID = 2 then use:
<tr class="ticket even status-open priority-low">
Etc.. Etc..
This is the current Foreach loop code I have based on the number fields to display in a Bootstrap table.
#foreach (var item in Model)
{
<tr class="ticket even status-new priority-low">
<td class="status"><span>#Html.DisplayFor(modelItem => item.TicketStatus.Status)</span></td>
<td class="number"><ul class="user-dashboard-tickets"><li class="user-dashboard-tickets"><span>#Html.DisplayFor(modelItem => item.TicketID)</span></li></ul></td>
<td class="assigned">#Html.DisplayFor(modelItem => item.TicketOwner.OwnerName)</td>
<td class="title"><h2>#Html.DisplayFor(modelItem => item.Title)</h2></td>
<td class="type">Problem</td>
<td class="assigned">test.user</td>
<td class="age">2 days</td>
</tr>
}
I don't know if you can put another foreach loop inside the loop? or add a query to the <tr> field?
you can put any code inside Razor view, even inside a loop, like this:
var statusClass = "";
switch (TicketStatus.StatusID){
case 1:
statusClass = "status-open";
break;
}
<tr class="ticket even #statusClass priority-low">

polymer expressions access property by its name

trying to render a table as a polymer element
<table>
<thead>
<tr>
<th template repeat='{{ column in columns}}'>
{{column.displayName}}
</th>
</tr>
</thead>
<tbody>
<tr template repeat='{{ row in data}}'>
<td template repeat='{{ column in columns}}'>
{{row[column.name]}}
</td>
</tr>
</tbody>
</table>
the following expression doesn't seem to work as i expected
{{row[column.name]}}
column.name is the property name that i want to access in the row object but it gives the following exception for all properties
NoSuchMethodError: method not found: '[]'
Receiver: Instance of 'Product'
Arguments: ["id"]
is this the right way to access a property by name?
my row model looks like this
class Product extends Observable{
int id;
String name;
String category;
}
One work around which i don't like is overloading the [] in the row class
operator [](String fieldName){
var im = reflect(this);
return im.getField(new Symbol(fieldName)).reflectee;
}
This should work if 'row' is a map.

How to Hide Table in MVC View when there is No Data?

I am populating my datatable using Linq.
I have hard-coded headers. And populating body columns with Linq. Following is my code.
<table id="tableID">
<thead>
<tr>
<th>Name</th>
<th>ID</th>
<th style="width:2%;"></th>
</tr>
</thead>
<tbody>
#if(Model.Values !=null)
{
foreach(var value in Model.Values)
{
<tr>
<td>#value.Name</td>
<td>#value.ID</td>
</tr>
}
}
</tbody>
</table>
What I am thinking to do here, if there is no data table should not be visible.I thought of moving my conditional check if model is returning null prior to table creation but it will throw exception. I am fairly new to MVC. Any suggestion is appreciated.
Thank you
Simply put one if around table as well to check if property is not null and count of that list is greater than 0 then table should be rendered.
#if(Model != null)
{
if(Model.Values != null && Model.Values.Count != 0)
{
<table id="tableID">
<thead>
<tr>
<th>Name</th>
<th>ID</th>
<th style="width:2%;"></th>
</tr>
</thead>
<tbody>
#foreach(var value in Model.Values)
{
<tr>
<td>#value.Name</td>
<td>#value.ID</td>
</tr>
}
</tbody>
</table>
}
}

Showing a dynamic table in GSP where column & data comes at run time

getting two arrays from controller and code is --
Sql db = new Sql(dataSource_wldb1) // Create a new instance of groovy.sql.Sql with the DB of the Grails app
def ivrColumns = []
db.eachRow(ivrColumnsQuery) {
rsRow ->
ivrColumns.add(rsRow.name) }
def ivrResults = []
db.eachRow(mssqlQuery) {rows ->
//print rows
ivrResults.add(rows)
}
one has all column names & other has all row data.as below-
return render(view:'xref',model:[ivrcolumns:ivrColumns,ivrresults:ivrResults] )
getting data in below format-
Columns
[ClientKey, Abbr, ConfigKey, Federal, State, DMA, Internal, Wireless, CRssing, CurfewExemption, CampaignID]
Data
[groovy.sql.GroovyResultSetExtension#12f8d75, groovy.sql.GroovyResultSetE
oovy.sql.GroovyResultSetExtension#12f8d75, groovy.sql.GroovyResultSetExtension#1
roovyResultSetExtension#12f8d75, groovy.sql.GroovyResultSetExtension#12f8d75, gr
tSetExtension#12f8d75, groovy.sql.GroovyResultSetExtension#12f8d75, groovy.sql.G
ion#12f8d75, groovy.sql.GroovyResultSetExtension#12f8d75]
view code is---
<g:if test="${ivrcolumns != null }">
<center>Database Location - WLDB1 <br>DB Name - IVR_GUARDIAN </center><br><br>
<table class="table loadTable" >
<thead>
<tr bgcolor="#f0f0f0" >
<g:each in="${ivrcolumns}" status="ii" var="columnivr">
<td nowrap>${columnivr}</td>
</g:each>
</tr>
</thead>
<tbody>
<g:each in="${ivrresults}" status="jj" var="hed">
<tr>
<g:each in="${ivrcolumns}" status="kk" var="col">
<td nowrap>${hed.col}</td> ///please suggest how to do it.
</g:each>
</tr>
</g:each>
</tbody>
</table>
now want to show in GSP page .i am able to display the column but having hard time to display data.not getting how the dot will be used to get correct data to each column.
Will appreciate any help.
thanks
Assuming that's just a sql result, you can just call ${ hed[ col ] } or ${ hed."$col" }

Resources