0

Component

export class AllUserComponent implements OnInit {
  //Here is saving all users from database
  allUsers: Array<Object>;
  roleName: any[] = []; //here I want roles property from each object from allUsers

  constructor(private userService: UserService) {}

  ngOnInit() {
    //Take from UserService getAll method and subscribe to add all users from database
    this.userService.getAll().subscribe(data => {
      this.allUsers = data.allUsers;
      console.log(this.allUsers)
    });

  }

Service

  getAll(): Observable<AllUsers> {
    return this.http.get<AllUsers>(this.url);
  }

Model

export interface AllUsers{
    allUsers: string[];
}

allUsers array

I want to get roles which are nested values in each object of allUser array and add it to roleName array and display in Roles column in table in HTML view.

4
  • this question actually has nothing to do with angular, it is just JavaScript. Commented Sep 19, 2019 at 11:21
  • Please show us what you tried as the mentioned example is all about fetching data. Commented Sep 19, 2019 at 11:22
  • could you show sample data of this.allUsers? Commented Sep 19, 2019 at 11:29
  • Have you tried the solution? Commented Sep 19, 2019 at 19:03

3 Answers 3

0

try like this:

this.allUsers.forEch(user => {
  user.roleNames.push(user.roles);
})
Sign up to request clarification or add additional context in comments.

Comments

0

Lets's change that string array first

export interface AllUsers{
    allUsers: User[]; // shouldn't be a string array?!
}

Add the user

export interface User {
  id: number;
  firstName: string;
  lastName: string; 
  email: string;
  password: string;
  roles: Role[];
}

And Role

export interface Role {
  id: number;
  name: string
}

Try to avoid using subscribe, use async pipe instead. You could use lodash to handle your arrays.

export class AllUserComponent implements OnInit {
  allUsers$: Observable<User[]>;
  distinctRoles$: Observable<Role[]>;

  constructor(private userService: UserService) {}

  ngOnInit() {
    // Take from UserService getAll method
    this.allUsers$ = this.userService.getAll().pipe(
      map((all: AllUsers) => all.allUsers),
    );

    // map the roles
    this.distinctRoles$ = this.allUsers$.pipe(
      map((allUsers: User[]) => _.flatMap(allUsers, 'roles')), // import * as _ from 'lodash'
      map((allRoles: Role[][]) => _.flatten(allRoles)),
      map((allRoles: Role[]) => _.uniq(allRoles)), // remove the line if you don't want disctinct
    );
  }

And "subscribe" to your Observables in your template with async pipe

<div *ngFor="let role of disctictRoles$ | async">

1 Comment

In this solution allUsers show users from database, but the problem is in display roles to appropriate user, because all roles in disctictRoles display in each row :/ ibb.co/wYCwGVK here is photo how it display
-1

As i understood; you need to show user roles besides its details, is that true?

I think you are using matTable or at least *ngFor; so you need to add a function to get appropriate roles; like:

getRoles(user: Object) {
    return user.roles.reduce((str, role) => {
        // add role name if this is the first role; else add role to string then return it    
        return str? str += ', ' + role.name: role.name;
    }, '');
}

It's not necessary to use reduce function; you can use temporary variable with an ordinary loop; but this is cleaner way.

Then from HTML you can call it in roles td; like:

<tr *ngFor="let user of allUsers">
    <!-- previous details-->
    <td> {{getRoles(user)}} </td>
</tr>

Read more about reduce function.

1 Comment

Thank you; he can move that function to a pipe.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.