I have a very puzzling problem. I have in my component a variable teams defined like this:
import { DateFunctionTeams } from '../_models/teams';
import { User } from '../_models/user';
import { AccountService } from '../_services';
import { first } from 'rxjs/operators';
#Component({
selector: 'app-raport-test',
templateUrl: './raport-for-date.component.html',
styleUrls: ['./raport-for-date.component.less']
})
export class RaportForDateComponent implements OnInit {
teams: Team[] = [];
...
}
The relevant part of my HTML looks like this:
<fieldset *ngFor="let team of teams">
<legend>{{team.function}} Users:</legend>
<div class="border border-primary">
<table id=scheduledTable class="table table-striped">
<thead>
<tr>
<th style="width:30%">Function</th>
<th style="width:30%">User</th>
<!--th style="width:30%">UserAvailability</th-->
<th style="width:10%"></th>
</tr>
</thead>
<tbody>
<tr *ngFor="let user of team.users">
<td>{{user.function}} </td>
<td>{{user.firstName}} </td>
</tr>
</tbody>
</table>
</div>
</fieldset>
The line with fieldset *ngFor="let team of teams" in HTML causes the error Type 'HTMLSelectElement' is not assignable to type 'NgIterable<any>'.
Interesting bit is that if I change the name teams to something else (e.g. tms) it works just fine.
Any help appreciated.
Related
in my project i have a table with information (FirstName, LastName, PhoneNumbre, Age, Date). i create an function making me to export file excel but i don't want to export all the data i need just to export (FirstName, LastName, Age).
this is what i do
excel.html :
<div class="panel-body table-responsive">
<table id="excel-table" class="table">
<thead>
<tr>
<th>FirstName</th>
<th>LastName</th>
<th>PhoneNumber</th>
<th>Age</th>
<th>Date</th>
</tr>
</thead>
<tbody>
<tr *ngFor='let excel of excels'>
<td>{{excel.FirstName}}</td>
<td>{{excel.LastName}}</td>
<td>{{excel.PhoneNumber}}</td>
<td>{{excel.Age}}</td>
<td>{{excel.Date}}</td>
<td>
<button (click)="exportexcel()">ExportExcel</button>
</td>
</tr>
</tbody>
</table>
</div>
excel.ts :
#Component({
selector: 'app-execls',
templateUrl: './execls.component.html',
styleUrls: ['./execls.component.css']
})
export class RegionsComponent implements OnInit {
constructor(private modalService: NgbModal, private fb: FormBuilder, private toastr: ToastrService) { }
fileName = 'ExcelFile.xlsx';
exportexcel(): void {
let element = document.getElementById('excel-table');
const ws: XLSX.WorkSheet = XLSX.utils.table_to_sheet(element);
const wb: XLSX.WorkBook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, 'Sheet1');
XLSX.writeFile(wb, this.fileName);
}
So I believe you are using sheetJS based on your code, and looking at the documentation, there is not a way to pass in columns you wish to display. https://docs.sheetjs.com/docs/api/utilities/#html-table-input. One option is to create another table with just the columns you want to display, but set that table to hidden.
<table id="excel-table-to-export" class="table" hidden>
<thead>
<tr>
<th>FirstName</th>
<th>LastName</th>
<th>Age</th>
</tr>
</thead>
<tbody>
<tr *ngFor='let excel of excels'>
<td>{{excel.FirstName}}</td>
<td>{{excel.LastName}}</td>
<td>{{excel.Age}}</td>
</tr>
</tbody>
</table>
I'm trying to access certain data from an API and having trouble doing so. Here is the structure of the JSON from the API:
I'm wanting to access Name, StateName & CityName within value to iterate through a table. I'm getting the obvious error "Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays", because ngFor isn't iterating through the array. How can I fix my code to iterate through the data to fill my table?
component.ts:
#Component({
selector: 'app-search',
templateUrl: './search.component.html',
styleUrls: ['./search.component.css']
})
export class SearchComponent implements OnInit {
customer: any;
constructor(private Service: CustomerDataService) { }
ngOnInit(): void {
this.getCustomerData();
}
public getCustomerData() {
this.Service.getCustomers().subscribe((data)=>{
console.log(data);
this.customer = data;
})
}
}
HTML:
<div class="container">
<form class="form-inline">
<div class="input-group mb-2">
<div class="has-clear">
<input type="text" name="search" required class="form-control" placeholder="Name" />
<button class="clear-data" type="reset"><i class="icon-close-bold-sm"></i></button>
</div>
<button type="submit" class="btn btn-primary mb-2 ml-3">Search</button>
</div>
</form>
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">City</th>
<th scope="col">State</th>
</tr>
</thead>
<tbody>
<tr *ngFor = "let customers of customer">
<td scope="row">{{customers.value.Name}}</td>
<td scope="row">{{customers.value.StateName}}</td>
<td scope="row">{{customers.value.CityName}}</td>
</tr>
</tbody>
</table>
</div>
</div>
The value is an array and not object, so
public getCustomerData() {
this.Service.getCustomers().subscribe((data)=>{
console.log(data);
this.customer = data.value;
})
}
and in your template
<tr *ngFor = "let customers of customer">
<td scope="row">{{customers.Name}}</td>
<td scope="row">{{customers.StateName}}</td>
<td scope="row">{{customers.CityName}}</td>
</tr>
Or you can just edit your template
<tr *ngFor = "let customers of customer.value">
<td scope="row">{{customers.Name}}</td>
<td scope="row">{{customers.StateName}}</td>
<td scope="row">{{customers.CityName}}</td>
</tr>
Consider using | async to access the observable directly in your html
<tr *ngFor = "let customer of customers$ | async">
<td scope="row">{{customer.Name}}</td>
<td scope="row">{{customer.StateName}}</td>
<td scope="row">{{customer.CityName}}</td>
</tr>
and in your component
customers$ : Observable<Customer> = this.getCustomerData();
You can update your getCustomerData with a map operator to return the list of Customers you have inside value property.
I have this code which parses JSON and list data into the table using ngFor.
The result will be like.
Yes, listing data into the table is working fine.
But how can I implement it to output single data of specific ID?
For example - I want the name of id=3 the output should be "Edward".
I can't figure out how to do this. Can someone help me or guide me?
Thanks.
app-components.ts
import { Component } from '#angular/core';
import {Http, Response} from '#angular/http';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
private data;
constructor(private http:Http){
}
ngOnInit(){
this.getData();
}
getData(){
this.http.get('/localhost/data.json')
.subscribe(res => this.data = res.json());
}
}
app-component.html
<table>
<tr>
<th>#</th>
<th>Name</th>
<th>Amount</th>
</tr>
<tr *ngFor="let info of data">
<td>{{info.id}}</td>
<td>{{info.name}}</td>
<td>{{info.amount}}</td>
</tr>
</table>
data.json
[
{
"id":"1",
"name":"John",
"amount":"112"
},
{
"id":"2",
"name":"Maria",
"amount":"44"
},
{
"id":"3",
"name":"Edward",
"amount":"40"
}
]
Please tell me that am I providing sufficient information or not.
You can use <ng-container> for the same, this have to use because you cannot apply two directives on a single element like we are using *ngIf and *ngFor.
<table>
<tr>
<th>#</th>
<th>Name</th>
<th>Amount</th>
</tr>
<ng-container *ngFor="let info of data">
<tr *ngIf='info.id == 3'>
<td>{{info.id}}</td>
<td>{{info.name}}</td>
<td>{{info.amount}}</td>
</tr>
</ng-container>
</table >
working example
Instead of adding an *ngIf directive , why don't you create a component separately to output only one table row ?
For example :
table.component.html will have :
<table>
<tr>
<th>#</th>
<th>Name</th>
<th>Amount</th>
</tr>
<tr>
<td>{{info.id}}</td>
<td>{{info.name}}</td>
<td>{{info.amount}}</td>
</tr>
</table>
and table.component.ts will have :
#Input() info : any;
Now you can loop over the <app-table [info]='info'></app-table> inside app-component.html also , you can just pass <app-table [info]='info[3]'></app-table> .
I have 2 components here: app.component.html and app-server.component.html
app.component.html
<table class="table" style="width:200px;">
<tr>
<td>Names</td>
<td>Age</td>
</tr>
<tr><app-server-element *ngFor="let student of students" [student]='student'></app-server-element></tr>
</table>
server-element.component.html:
<td class="column">{{student.name}}</td>
<td class="column">{{student.age}}</td>
but the result is like this why?:
In addition to the problem others have suggesting - there seems to be another problem. Your <app-server-element *ngFor="let student of students" [student]='student'></app-server-element> acts as a cell because it is a direct child of your tr. The td elements inside app-server-element have no effect. You could use replace in your directive to get rid of the wrapper - that way the td element would be a direct child of the tr element and it would work as expected.
Edit
After gathering more information regarding your problem, please make the following changes to your code:
Change the server-element.component.ts to:
import { Component, OnInit, Input } from '#angular/core';
#Component({
selector: '[appServerElement]',
templateUrl: './server-element.component.html',
styleUrls: ['./server-element.component.css']
})
export class ServerElementComponent implements OnInit {
#Input()
appServerElement: { name: string, age: string };
constructor() {
//
}
ngOnInit() {
//
}
}
and change selector: 'app-server-element' to selector: '[appServerElement]'.
Change the app.component.html to the following:
<table class="table" style="width:200px;">
<tr>
<td>Names</td>
<td>Age</td>
</tr>
<tr [appServerElement]="student" *ngFor="let student of students"></tr>
</table>
As ankit suggested you need to iterate of <tr>:
<table class="table" style="width:200px;">
<tr>
<td>Names</td>
<td>Age</td>
</tr>
<tr *ngFor="let student of students"><app-server-element *ngFor="let student of students" [student]='student'></app-server-element></tr>
your code iterate over app-server-element which results:
<tr>
<app-server-element></app-server-element>
<app-server-element></app-server-element>
<app-server-element></app-server-element>
<app-server-element></app-server-element>
</tr>
while you want: <tr><app-server-element></app-server-element></tr>
<tr><app-server-element></app-server-element></tr>
<tr><app-server-element></app-server-element></tr>
I'm trying to make a table with angularJs2 2.0.0-beta.0. This table lists items. I would decouple the item from the list.
I have this code:
app.item.list.html
<table class="table table-condensed" [hidden]="items?.length==0">
<thead>
<tr>
<th >id</th>
<th >col 2</th>
<th >col 3</th>
<th >col 4</th>
<th >col 5</th>
<th >col 6</th>
</tr>
</thead>
<tbody>
<tr *ngFor="#item of items" >
<item-detail [item]="item"></item-detail>
</tr>
</tbody>
</table>
The app.item.list.ts
import {Component, EventEmitter, Output, Input, OnChanges, SimpleChange} from 'angular2/core';
import {FORM_DIRECTIVES} from 'angular2/common';
import {Item} from './model/model.item';
#Component({
selector: 'item-list',
templateUrl: 'app/app.item.list.html',
directives: [FORM_DIRECTIVES, Item]
})
export class ItemList{
#Input() Items:Array<Item> = new Array();
public item: Item;
}
the app.item.html
<td >{{item.id}}</td>
<td >{{item.col1}}</td>
<td >{{item.col2}}</td>
<td >{{item.col3}}</td>
<td >{{item.col4}}</td>
<td >{{item.col5}}</td>
And the app.item.ts
import {Component, Input, EventEmitter, Output, OnChanges, SimpleChange} from 'angular2/core';
import {FORM_DIRECTIVES, NgFor} from 'angular2/common';
#Component({
selector: 'item-detail',
templateUrl: 'app/app.item.html',
directives: [ FORM_DIRECTIVES, NgFor]
})
export class Item{
#Input() item:Item;
}
The Items informations are all displayed, but there is a format problem. All my items are raggrouped under the first column of the header (the id column).
But I want to have the item.id under the id header, the item.col1 under col1 ....
What can I do having the list and the item decoupled?
P.S.: When they were in a single html and ts file, it worked well
Ok I recived an answer on Github, and I post the solution here:
I have to change app.item.list.html
and app.item.ts
#Component({
selector: '[item-detail]',
...
})
export class Item{
#Input('item-detail') item:Item;
}