-1

I am doing a small project on Angular and one of the tasks is display 2 buttons ONLY if an admin is logged in. Now, to check if the admin is logged in, I have a method inside user.service.ts file.

public getRole(): string {
    return sessionStorage.getItem('role');
}

Now, I have a component where I am displaying the buttons. In the .ts file, I imported the user service of course.

import { UserService } from 'src/app/services/user/user.service';

and I added this code to the constructor of the same .ts file.

private userService: UserService

Then, in the html file, I am checking like this:

<div *ngIf="this.userSevice.getRole() == 'ADMIN'">
                            <a class="btn btn-secondary col-md-12" routerLink='/boat-offer' routerLinkActive="active">Delete</a>
                            <a class="btn btn-success col-md-12" routerLink='/boat-offer' routerLinkActive="active">Edit</a>

</div>

However, in console, I am getting the error:

ERROR TypeError: Cannot read property 'getRole' of undefined

Whats even more annoying is the fact that the project I am working on was given to us by our lecturer and everyone is using the same version where these getRole method was given to us. However, on others' project it works and on mine it does not. What am I doing wrong please?

5
  • Paste your full .ts code Commented Jan 22, 2020 at 21:39
  • What does <span>{{userService.getRole() | json}}</span> display? Commented Jan 22, 2020 at 21:39
  • @Reactgular it displays ADMIN Commented Jan 22, 2020 at 21:41
  • Check and make sure there aren't any hidden spaces in the string. Commented Jan 22, 2020 at 21:43
  • @Reactgular there isn't but even if there is, if I do it to != 'ADMIN' it's supposed to work no? It doesn't work btw.. It just shows the same thing Commented Jan 22, 2020 at 21:45

3 Answers 3

2

You wrote userSevice instead of userService in your html

Sign up to request clarification or add additional context in comments.

3 Comments

First of all I tried doing it public and it did not work and secondly, earlier today, I tried literally that and it gave the same answer.. I do now know what's wrong to be honest..
You wrote userSevice in your html... or is it just a typo?
Thanks.. Must be all the tiredness
1

Another thing you can do is wrap the string comparison inside a method of the component, so you do not call the service from the HTML.

isAdmin() {
    return this.userSevice.getRole() === 'ADMIN'
}

and in the HTML

<div *ngIf="isAdmin()">
     <a class="btn btn-secondary col-md-12" routerLink='/boat-offer' routerLinkActive="active">Delete</a>
     <a class="btn btn-success col-md-12" routerLink='/boat-offer' routerLinkActive="active">Edit</a>

</div>

Another thing is that you should use === instead of == when comparing strings, as mentioned here

Be aware that sessionStorage.getItem('role') should not be an asynchronus method, if this is the case you would like to use async/await

Verbose example:

async getTheRoleExample(): string {
    const role = await sessionStorage.getItem('role');
    return role;
}

isAdmin(){
    return this.getTheRoleExample() === 'ADMIN'
}

1 Comment

This did it for me! Thanks a lot!
0

When you need to debug something like this. You should change the function to log what is happening.

public getRole(): string {
    const role = sessionStorage.getItem('role');;
    console.log('getRole', role);
    return role;
}

It's not a good idea to use expressions in the template to compare strings. If the term "ADMIN" changes you have to search all the source code to find the usages. So instead add a method to the service.

public isAdmin(): boolean {
   const role = this.getRole();
   const isAdmin = role === 'ADMIN';
   console.log('isAdmin', isAdmin);
   return isAdmin;
}

You shouldn't call a shared service method directly from the template. Calling functions in template expressions triggers Angular to mark the expression as impure, and then the function is called excessively.

Instead, assign the value to a property in ngOnInit()

@Component({
   ...
   template: `
     <div *ngIf="isAdmin">
         <a class="btn btn-secondary col-md-12" routerLink='/boat-offer' routerLinkActive="active">Delete</a>
         <a class="btn btn-success col-md-12" routerLink='/boat-offer' routerLinkActive="active">Edit</a>
     </div>
   `
})
export class ExampleComponent implements OnInit {
   isAdmin: boolean;

   constructor(myService: MyService) { }

   ngOnInit() {
      this.isAdmin = myService.isAdmin();
   }
}

By this point you should have enough feedback in the console to see what is happening.

getRole ADMIN
isAdmin true

If you get stuck, then use a debugger; to open the browser debugger tools. You can then step inside your service and see what is happening.

   ngOnInit() {
      debugger;
      this.isAdmin = myService.isAdmin();
   }

Comments

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.