Angular 2+ - Parse json data and output only single specific data - json

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

Related

Is `teams` word a reserved word in angular?

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.

Angular: Reset index value in the same template

I have a template of 3 tables having same JSON as parent like this.
<tbody>
<ng-container *ngFor="let row of reportingData.RecommendationData; let i=index">
<tr *ngIf="row.swRecommendations">
<td>{{i+1}}</td>
<td> {{row.swRecommendations.deviceID}}</td>
</tr>
</ng-container>
</tbody>
Another table body
<tbody>
<ng-container *ngFor="let row of reportingData.RecommendationData; let j=index">
<tr *ngIf="row.licenseRecommendations">
<td>{{j+1}}</td>
<td> {{row.licenseRecommendations.deviceID}}</td>
</tr>
</ng-container>
</tbody>
All these tables are in the same template. I'm assigning index values to different variables(i & j) but increment is happening i.e. if first table is having 5 rows, second table is starting with 6 not 1. How to fix this?
I tested you'r code and indexes are starting from 0 .
Please review my code.
Component.html
<h1>First Table</h1>
<table>
<tr>
<th>Id</th>
<th>Name</th>
</tr>
<ng-container>
<tr *ngFor="let a of array;let i = index">
<th>{{i + 1}}</th>
<th>{{a.name}}</th>
</tr>
</ng-container>
</table>
<h1>Second Table</h1>
<table>
<tr>
<th>Id</th>
<th>Name</th>
</tr>
<ng-container>
<tr *ngFor="let a of array;let j = index">
<th>{{j + 1}}</th>
<th>{{a.name}}</th>
</tr>
</ng-container>
</table>
Component.ts
import { Component } from '#angular/core';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styles: ['./app.component.scss']
})
export class AppComponent {
constructor() {}
public array = [
{ id: 1, name: 'aaa'},
{ id: 2, name: 'bbb'},
{ id: 3, name: 'ccc'},
{ id: 4, name: 'ddd'},
{ id: 5, name: 'eee'},
{ id: 6, name: 'fff'},
]
}
H recently faced the same issue, since we are indexing it and increment it will be like that, the solution of this problem is like this Filter your data in the ts
this.a= this.reportingData.filter(x => x.swRecommendations);
this.b= this.reportingData.filter(x => x.licenseRecommendations);
<tr *ngFor="let row of a"> <tr *ngFor="let row of b">,
and then remove the if condition and iterate the data in HTML like this let row of reportingData , editing needed based on your consition in ts

Not able to Retrieve data from firebase using keys in angular 2

Hi I want to iterate the data of firebase and need to display it in table.
Below is my firebase structure.I want to display the bill to, email id and po number in the tables.i can see the data in console.log, but its not populating in tables.
EDI855
Bill To
-L9ac7clRzSVT-EfGxYv:
"123456789"
-L9acDp2k34qDpubJFr6:
"123456780"
Email Id
-L9ac7cxYSALI3Ogj-nt:
"test#gmail.com"
-L9acDp87NO83OQutasK:
"test1#gmail.com"
Po Number
-L9ac7cvtNNzg7hYa355:
"123456789"
-L9acDp4PPOSo9VL9ysB:
"VV002"
Below is my html table:
div class="table-responsive">
<table class="table">
<thead>
<tr>
<th>No</th>
<th>Bill To</th>
<th>Requested by</th>
<th>Po Number</th>
</tr>
</thead>
<tbody>
<tr>>
<td *ngFor="let x of items">{{x.$value}}</td>
</tr>
</tbody>
</table>
Below is my firebase code:
constructor(public af: AngularFire) {
af.database.list('/EDI855').subscribe(x =>{
this.items=x;
console.log(this.items)
}
Try implementing your query in the init event instead
export class MyComponent implements OnInit {
items;
constructor(public af: AngularFire) {
}
ngOnInit() {
this.af.database.list('/EDI855').subscribe(x =>{
this.items=x;
}
}
Or even better, to get the most out of the real-time database, you should consider using the async pipe. When you do that, your app will react to any changes on your data and immediately refresh the UI.
<td *ngFor="let x of items | async">{{x.$value}}</td>
Just that in this case, remember that you're changing the type of items (it is no longer the list of items, but an observable of items), than therefore, no need to subscribe to it. The async pipe will do the work.
constructor(public af: AngularFire) {
this.items = af.database.list('/EDI855');
}

why table cell is not reading the table row in parent component?

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>

Angular2 with a table and a custom element on it

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