Search code examples
htmlangulartypescriptangular-ng-if

Show options according users


I have 3 users Admin, Supervisor and Student. What I want to do is, Admin adn supervisor can edit and delete students data while student can only delete and edit his own data. He can only view other's data.

I get roles for user in json like below:

Admin: ["Administrator"]
Supervisor: ["Supervisor", "Guest"]
Student: ["Student", "Guest"]

Below is what I am trying to do:

Exhibits.component.ts

   getCurrentUser() {
     this.userService.getCurrent()
       .then(
         (response) => {
           this.currentUserId = response.id;
            for (let role of response.roles) {
             if (role === 'Administrator') {
               this.canEdit = true;
             } else if (role === 'Supervisor') {
               this.canEdit = true;
             } else if (role === 'Student') {
               this.canEdit = false;
             }
          }
        }
      ).catch(
        (error) => console.log(error)
      );
  }

Exhibits.component.html

  <div *ngIf="canEdit && this.currentUserId === exhibit.userId">
    <button md-icon-button click-stop-propagation color="primary" [routerLink]="['/mobile-content/exhibits/edit', exhibit.id]"
      title="{{ 'edit' | translate }}">
      <md-icon>{{ !inDeletedPage ? 'edit' : 'remove_red_eye'}}</md-icon>
    </button>
    <button md-icon-button click-stop-propagation color="warn" (click)="deleteExhibit(exhibit)" *ngIf="!exhibit.used && !inDeletedPage"
      title="{{ 'delete' | translate }}">
      <md-icon>delete_forever</md-icon>
    </button>
  </div>

I am trying to show Exhibits which i got in array according to userId. It means, in exhibits json response, I am getting "userId" which i am trying to match with current user's userId. Oly thing is student can only see delete and edit option for his created exhibit but admin and supervisor can see edit and delete option for all users created exhibits.

Can anyone help me to figure this out?


Solution

  • First, I would suggest to converting this to an enum on both your front and back end, as opposed to relying on string matching.

    But judging from your code, if I'm reading correctly, no student would ever be able to have an edit and delete button because you're always setting to false on that user type.

    Your second problem is going to be in your *ngIf that states the following:

    *ngIf="canEdit && this.currentUserId === exhibit.userId"
    

    This is going to result in these buttons always being hidden at unwanted times because even on administrators and other users you need the conditional of the user ids matching to evaluate to true. You also should not need to specify this in a template.

    Personally, I would do something more like this.

    getCurrentUser() {
      this.userService.getCurrent()
        .then(
          (response) => {
            this.currentUserId = response.id;
             for (let role of response.roles) {
              if (role === 'Administrator') {
                this.canEdit = true;
              } else if (role === 'Supervisor') {
                this.canEdit = true;
              } else if (role === 'Student') {
                if (this.currentUserId === this.exhibit.userId) {
                 this.canEdit = true;
                } else {
                 this.canEdit = false;
                }
              }
           }
         }
       ).catch(
         (error) => console.log(error)
       );
    }
    

    You would then be able to just change your template *ngIf to:

    *ngIf="canEdit"
    

    As an aside, you may also want to change your checking of the role to a switch statement, it is more performant and will make your code cleaner.

    OR you could do this, which would accomplish the same thing.

    getCurrentUser() {
      this.userService.getCurrent()
        .then(
          (response) => {
            this.currentUserId = response.id;
             for (let role of response.roles) {
              if (role === 'Administrator') {
                this.canEdit = true;
              } else if (role === 'Supervisor') {
                this.canEdit = true;
              }
           }
         }
       ).catch(
         (error) => console.log(error)
       );
    }
    

    Template code would be:

    *ngIf="canEdit || this.currentUserId === exhibit.userId"