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.
Related
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.
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);
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>
I am new to angular4 working over MEAN Stack My data is coming from Mongo DB in the form of a list of hyperlinks.Now I want that when I click over each link in UI, it should be opened as a separate link but as of now, it is opening a combined link i.e. it is taking as a single entry.
I am trying to pass ';' after each link in Mongo Db and at the UI level I am trying to separate/split based on each ';'.
<tbody>
<tr *ngFor="let item of items">
<td> {{ item.SNo }}</td>
<td> {{ item.UseCase }}</td>
<td>
{{ item.ReferenceMaterials }}
</td>
</tr>
</tbody>
My structure of JSON is:
{
"_id":"537437505593",
"SNo" :"1",
"UseCase":"hfwioegepepohgy",
"Focus":"hellow world",
"RefernceLinks":"link1";"link2";"link3"
}
These links are rendered to UI as link1;link2;link3.Clicking over link1 click over all other links also.Kindly help.
You need to create a custom pipe
#Pipe({
name: 'split'
})
export class SplitPipe implements PipeTransform {
transform(val:string, separator:string):string[] {
return val.split(separator);
}
}
And use it like this
<a *ngFor="let link of item.ReferenceMaterials|split" href="{{link}}">{{link}}</a>
Or item.RefernceLinks like your json shows...
Use ngFor.
<a *ngFor="let link of item.ReferenceMaterials" href="{{link}}">{{link}}</a>
So I have a List that I am returning from rest service. Now, I want to display this object in column format and now in row one. So it would be something like this:
firstName: Bob Alice
LastName: Doe Joe
EmailId: bob#xyz.com alice#abc.com
ContactNo: 123123 12444
So how can I use ng-repeat over here:
<tr>
<th>firstName:</th>
<td>('Name should be displayed here')</td>
</tr>
You can use ng-repeat on the td element.
<tr>
<th>firstName:</th>
<td ng-repeat="person in people">{{person.firstName}}</td>
</tr>
<tr>
<td ng-repeat="person in people">{{person.lastName}}</td>
</tr>
If you declare the keys of the objects you're iterating through, you can nest your ng-repeats so that you don't need to declare each row over and over. Do the following and nest them instead:
In the Angular App:
/*for the data*/
var personKeys = ['firstName', 'LastName', 'EmailID', 'ContactNo'];
var people = [
{
firstName: 'Bob',
LastName: 'Doe',
EmailID: 'bob#xyz.com',
ContactNo: 123123
},
/* etc */
];
/*don't forget to reference this in your controller with something like: */
this.pKeys = personKeys;
this.people = people;
In your HTML:
<table ng-controller='MyController as personList'>
<tr ng-repeat='key in personList.pKeys'>
<th>{{key}}</th>
<td ng-repeat='person in personList.people'>
{{person[key]}}
</td>
</tr>
</table>
This still has the problem of iterating over each person |attributes| times, instead of just once. I'm sure there is a clever way to only iterate once, memoize, and draw up the table without having to go through your entire data set many times, so that the runtime doesn't grow so quickly as you expand your data.