0

I'm creating a website at angular 6

In my project user can be 3 types: admin, company, customer.

In my header component i have 3 menus under ngIf which need to be shown according to your login details.

Somehow I cannot communicate between those two components and launch header's function in order to change the view. didn't work with the service I have either.

I'll post some of the code here and hope someone help me out :)

// header component: 
export class HeaderComponent implements OnInit {

  guestMenu: boolean = true;
  adminMenu: boolean = false;
  companyMenu: boolean = false;
  customerMenu: boolean = false;

  //change site view to admin
  admin() {
    this.adminMenu = true;
    this.companyMenu = false;
    this.customerMenu = false;
    this.guestMenu = false;
  }
  //change site view to company
  company() {
    this.adminMenu = false;
    this.companyMenu = true;
    this.customerMenu = false;
    this.guestMenu = false;
  }
  //change site view to customer
  customer() {
    this.adminMenu = false;
    this.companyMenu = false;
    this.customerMenu = true;
    this.guestMenu = false;
  }
  constructor() {}

  ngOnInit() {

  }

}


// login component: 


export class LoginComponent implements OnInit {


  constructor(private dataService: DataService) {}

  loginUser(username, password, type) {
    console.log(username.value, password.value, type.value);
    switch (type.value) {

      case "ADMIN":
        {
          this.dataService.getLoginResponse(username.value, password.value,
            type.value).subscribe(res => {})
        }
        break;

      case "COMPANY":
        {
          this.dataService.getLoginResponse(username.value, password.value,
            type.value).subscribe(res => {})
        }
        break;
      case "CUSTOMER":
        {
          this.dataService.getLoginResponse(username.value, password.value,
            type.value).subscribe(res => {})
        }
        break;
    }
  }

  ngOnInit() {}

}
mplungjan
  • 169,008
  • 28
  • 173
  • 236
  • Possible duplicate of [How to communicate between component in Angular?](https://stackoverflow.com/questions/30501577/how-to-communicate-between-component-in-angular) – Carsten Jun 26 '18 at 05:19

1 Answers1

0

I would create an authentication service to act as a middle layer between the two components and perform communication using an rxjs/Subject.

import { Subject, Observable } from 'rxjs';

export class AuthenticationServce {
    userType$: Observable<string>;
    private userType: Subject<string>;

    constructor() {
        this.userType = new Subject<string>();
        this.userType$ = this.userType.asObservable();
    }

    public updateUserType(userType: string): void {
        this.userType.next(userType);
    }
}

In your login.component:

constructor(
    private dataService: DataService,
    private authenticationService: AuthenticationService,
) { }

loginUser(username, password, type): void {
    ...
    this.authenticationSubject.updateUserType(type.value);
    ...
}

And, lastly, in your header.component:

constructor(private authenticationService: AuthenticationService) {
    this.authenticationService.userType$.subscribe(userType => {
        switch (userType) {
            case "ADMIN":
                this.admin();
                break;
            // Other case statements
        }
    });
}
Simon K
  • 2,762
  • 1
  • 11
  • 20
  • thanks that solved my problem. im now facing another one which GuestMenu is true and all the rest are false everytime i refresh the page. any solution? @Simon K – אוראל הינדי Jun 26 '18 at 10:43
  • When the page is refreshed, you should be storing the user type somewhere to avoid making the user login again. You should read it from there and call the service to set the user type when you're setting up the user permissions. If you're not sorting their login, I would recommend you start and the easiest place to put it is in SessionStorage – Simon K Jun 26 '18 at 14:37
  • how should i do that without SessionStorage? where do i define what gonna happen when page is refreshed ? – אוראל הינדי Jun 26 '18 at 21:53
  • In a single page application (SPA), a user's session must be stored in their browser as the server is stateless. A typical way of doing this is that when the user logs in via an API, they are given some sort of token which might include some basic details (name, role/user type) and a unique key. Whether or not you use a token, you must store something to identify the user and it must be in a place that isn't wiped on a refresh. Those places are SessionStorage and LocalStorage. – Simon K Jun 26 '18 at 22:45
  • As for what happens on a refresh, your entire app is reinitialised so every constructor and OnInit that's relevant to the current route is going to get called so refresh code should typically go into the highest/root level component's `ngOnInit` function. – Simon K Jun 26 '18 at 22:47
  • got it. so you recoomend session storage or local storage? – אוראל הינדי Jun 26 '18 at 22:49
  • I personally prefer Session as it gets deleted when the user closes their browser. The decision is dependent on your Application's requirements though and if you want the login to live on after a user closes their browser (so they don't have to re-authenticate when they come back). They both have their own drawbacks though so I strongly recommend you do some research before deciding. – Simon K Jun 26 '18 at 22:57
  • thanks a lot. so i will save the type as session storage right after the login method and then in header component ill load the navbar in the constructor according to the type which is saved in storage – אוראל הינדי Jun 26 '18 at 23:12
  • That's about the gist of it though I would recommend loading the navbar in the OnInit method rather than in the constructor. That's more of a Best Practices type of thing though. – Simon K Jun 26 '18 at 23:18
  • WORKS PERFECT !! THANKS A LOT – אוראל הינדי Jun 27 '18 at 09:00