HTML 5 Angular 10: Display array attribute values using EXL - html

I'm trying to display user info using HTML and Angular 10, here my User Object:
export interface User {
email: string;
password: string;
userName: string;
roles: Role[];
}
export interface Role {
name: string;
}
Here's my html code
<tbody>
<tr *ngFor="let user of users" >
<td>{{user.name}}</td>
<td>{{user.username}}</td>
<td>{{user.email}}</td>
<td>{{user.password}}</td>
<td>{{user.roles}}</td>
</tr>
</tbody>
How can i get Role.names for every User separated by ",".
like:
name username email password role
user adminName admin#mail.com admin123 ADMIN, MODERATOR, USER

Create separate function where you can get generated value for displaying
function getUserRoles(roles) {
return roles.map((role) => role.name).join(‘ ,’)
}
<td>{{getUserRoles(user.roles)}}</td>

EDITED:
My way of doing this is another *ngFor at the end of the table, something like this:
<tbody>
<tr *ngFor="let user of users" >
<td>{{user.name}}</td>
<td>{{user.username}}</td>
<td>{{user.email}}</td>
<td>{{user.password}}</td>
<td *ngFor="let role of user.roles">
{{role.name}}
</td>
</tr>
</tbody>
You have to use some CSS to properly display the last row and add a comma as well.

Related

angular fake API using jasonplaceholder, getting details after clicking button

I am working on a dummy API with jsonplaceholder, I am getting all posts after clicking button, but i wanna get userid and title on load,and after clicking title need to get that particular body of that id How can i achieve this.
in jasonplaceholder there are 100 posts with id,title,body. on clicking getdata i need only id and title after when I click on title I need to get body as either in paragraph or popup or something.
html
<button (click)="get()">Get Data</button>
<div class="col-md mt-4 mb-4">
<table class="table table-bordered">
<thead>
<tr>
<th>id</th>
<th>title</th>
<th>body</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let d of data">
<td><span>{{d.id}}</span></td>
<td><span>{{d.title}}</span></td>
<td><span>{{d.body}}</span></td>
</tr>
</tbody>
</table>
</div>
ts
get(){
this.userservice.getData().subscribe((data) =>{
console.log(data)
this.data = data
})
}
service
getData():Observable<any>{
const url = "https://jsonplaceholder.typicode.com/posts";
return this.http.get(url)
}
A simple solution would be to use *ngIf and a variable, eg. selectedId
<td (click)="showBody(d.id)"><span>{{d.title}}</span></td>
<td *ngIf="selectedId === d.id"><span>{{d.body}}</span></td>
Then in your component, initiate it:
selectedId: any = null;
and
showBody(id: number){
this.selectedId ? this.selectedId = null : this.selectedId = id;
}
so that it would hide the body if you click on the title again.
As I understand, you need to get the id of the element you clicked on it to show the element's body.
so to achive this, you can write something like this:
component.html
<tr *ngFor="let d of data" (click)="setBody(d)">
<td><span>{{d.id}}</span></td>
<td><span>{{d.title}}</span></td>
</tr>
<!-- Show selected item body here -->
<h1>Selected item body</h1>
<p>{{selectedItemBody}}</p>
component.ts file
[Optional]: you can define the POST interface top of your ts file to have more clean code:
interface POST {
id: number;
title: string;
body: string;
}
setBody(post: POST) {
this.selectedItemBody = post.body;
alert(this.selectedItemBody); // you can remove this alert
}
I provided you this sample working code here in stackblits

Cannot create property 'selected' on string, using ngModel with Angular

so I'm trying to use [(ngModel)] like this:
<div class="items">
<tbody>
<tr *ngFor="let account of this.accounts">
<td>
<input type="checkbox" [(ngModel)]="this.account.name.selected" name="account">
{{account.name}}
</td>
</tr>
</tbody>
</div>
My accounts is created and filled in the component: accounts: Account[] = [];
My Account object:
export class Account {
name: string;
surname: string;
}
I'm getting ERROR TypeError: Cannot create property 'selected' on string 'John'
I saw this thread: Cannot create property 'selected' on string 'Information Technology' angularjs But didn't quite understand how to apply mentioned fix to my case, maybe because I'm using Angular and not AngularJS. Would be glad if anyone could help a bit understanding the problem here?
It looks like you need to have selected property in your array. So to avoid polluting Account class, you can use map method:
let withSelectedProperty = this.accounts.map(s=> ({...s, selected: false}));
And HTML:
<tr *ngFor="let account of withSelectedProperty">
<td>
<input type="checkbox" [(ngModel)]="account.selected" name="account">
{{account.name}}
</td>
</tr>
UPDATE:
You can use method filter to get all selected values:
let onlySelected = this.withSelectedProperty.filter(f => f.selected);

Angular write data lines dynamically to a table

In my project I getting the data from JSONPlaceholder - Users
I'm new in Angular, so if you find something stupid in the way I get the data please warn me.
dataFromServer;
constructor(private http: HttpClient){
this.dummyPromise.then(
response => {
console.log("response from dummy promise:", response);
this.dataFromServer = response;
},
error => {
console.log("Error happened with dummy promise:", error)
}
)
}
dummyPromise = new Promise((resolve, reject) => {
this.http.get('https://jsonplaceholder.typicode.com/users').subscribe(data => {
console.log(data);
this.dataFromServer = data;
});
//resolve(returnData);
});
Problem is, in my HTML file, I write the data into a table like this:
<tr *ngIf="dataFromServer">
<td>{{dataFromServer[0].id}}</td>
<td>{{dataFromServer[0].name}}</td>
<td>{{dataFromServer[0].username}}</td>
<td>{{dataFromServer[0].email}}</td>
</tr>
<tr *ngIf="dataFromServer">
<td>{{dataFromServer[1].id}}</td>
<td>{{dataFromServer[1].name}}</td>
<td>{{dataFromServer[1].username}}</td>
<td>{{dataFromServer[1].email}}</td>
</tr>
... for all the 10 people. I want to do it dynamically, as many lines as many people's data I get.
I think that you should try to use *ngFor instead of *ngIf. I will give you an example.
<tr *ngFor="let data of dataFromServer">
<td>{{data.id}}</td>
<td>{{data.name}}</td>
<td>{{data.username}}</td>
<td>{{data.email}}</td>
</tr>
So, it will repeat for every object in your dataFromServer
use ngFor to iterate on an array of data:
<table *ngIf="dataFromServer">
<tr *ngFor="let item of dataFromServer">
<td>{{item.id}}</td>
...
</tr>
</table>
the ngIf condition on the table will prevent console errors/rendering issues if dataFromServer is null/undefined before receiving from your API
You can replace your html code as bellow
<tr *ngFor="let row of dataFromServer">
<td>{{row.id}}</td>
<td>{{row.name}}</td>
<td>{{row.username}}</td>
<td>{{row.email}}</td>
</tr>
You can use *ngFor to do it. It's pratically a for in the html. As an example we assume that we have a component like this :
private users: User[] = [];
ngOnInit(){
this.service.getUser()
.subscribe(userList => {
this.users = userList;
});
}
The User class :
export class User {
public id: number;
public name: string;
}
You can use the *ngFor in your html like this way :
<span *ngFor="let user of users">
UserID: {{user.id}} - User Name: {{user.name}}
</span>
So basically, related to your code, just put in an object of User the json data you get from the http call, then modify the html like this way :
<tr *ngFor="let user of users">
<td>{{user.id}}</td>
<td>{{user.name}}</td>
.....
</tr>

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

Angular 2 DataBinding displaying a list in same <td></td>

I am new to Angular2 so any help is much appreciated.
I am getting data in the form of a list<user>. Each user has a list of roles. So in typescript I created this user type:
export class User {
id: string;
firstName: string;
middleName: string;
lastName: string;
email: string;
roles: Role[];
}
I am parsing the data in above type form. 'users' is an array users: Array<User>; in that component.
Displaying the data I want to list out Role[] into comma separated values in like <td>admin, customer, writer</td>,
but what I am getting instead is:
<td>admin</td>
<td>customer</td>
<td>writer</td>
Here is the code I am trying:
<tr *ngFor="let user of users">
<td>{{user.id}}</td>
<td>{{user.firstName +' '+ user.middleName+' '+user.lastName}}</td>
<td>{{user.email}}</td>
<td *ngFor="let role of Role">{{role.name}}</td>
<td><button type="button" class="btn btn-primary " (click)="roleOnClick(user)"></button></td>
</tr>
How can I achieve something like <td> admin, customer, writer</td>?
<td *ngFor="let role of roles">{{role.name}}</td>
That line above says to repeat the <td> tag for each element of the Role array, which is why you're getting the behaviour that you're seeing.
If you just want to get a comma separated list of roles, you may just want to use a simple function call on the role array, for eg:
<td> {{ roles.join(', ') }} </td>
join is a function on the standard JavaScript Array class that allows you to combine the elements of the array simply. The parameter to the function is the text you want to place between each member of the array.