So I am creating a SPA on angular and i have to change the header based on the user. I created an archiecture component which has the header and footer and i have set it to the app component with the selector so that it is the starting point. So on start architecture component (header footer only) will check with ngOnInIt if user has logged in and if not navigate to login if user is logged in navigate to Home. I have set ngIf on header <li> to show if student, lecturer or staff is logged in. But the problem is i cant reload on other pages or it will route to either login page or home page after checking if user is logged in cause the architecture (header footer ) component is used as the starting point and called from app component with selector. Furthermore i have to call
reloadPage(): void {
window.location.reload();
}
to load the header based on the user after logging in and before navigating to home page.
I have found some content on ng-template and using observables to deal with this but im kind of confused on it . I hope someone can help me on this problem. As im new to angular and server side programming what i say and have used might be incorrect and confusing so if theres any advices on routing, services , subscribing etc ill be really thankful!!
EDIT ............................................................................
Alright So the project i am creating is an online learning platform for a institution so in app component i have given the router outlet. What i want is on loading the site to route to login if user is not logged in and is not contained within the storageService i created and used to check if userLoggedIn on ngOnInIt so then after validating login i want to navigate to architecture and then to home page with the architecture component displaying only the required header items for the logged in user type . Im struggling on coming up with the right logic to achieve this)))
CodePudding user response:
A very simple example:
Build a UserService
:
export interface User {
name: string;
password: string;
role: string;
}
export class UserService {
private currentUserSubject: Subject<User> = new Subject<User>();
getCurrentUserSub() {
return this.currentUserSubject.asObservable();
}
login() { // Here we fake a login for this example
const loggedInUser = { name: "Testuser", passwort: "Secret", role: "SuperAdmin" };
this.currentUserSubject.next(loggedInUser); // Set the user
}
}
Now the HeaderComponent
(or any other)
...
export class HeaderComponent implements onInit, onDestroy {
currentUser!: User;
userSub!: Subscription;
constructor(private userService: UserService) {}
ngOnInit(): void {
this.userSub = this.userService.getCurrentUserSub().subscribe(data => {
this.currentUser = data; // Every time the user changed in the Service, we get info
});
}
ngOnDestory(): void {
this.userSub.unsubscribe(); // Important!
}
}
Headers HTML
<div *ngIf="currentUser">
Hello {{ currentUser.name }}! Your role is <b>{{ currentUser.role }}</b>
</div>
<div *ngIf="!currentUser">
Nobody is logged in.
</div>
Now in all other Components
you can (if needed) bind the user in the same way like in HeaderComponent
.
In LoginComponent
we now call the login method:
...
login() {
this.userService.login();
}
...
So all components they subsribed to the LoginService
currentUserSubject
(getCurrentUserSub() - use always a Observable
never directly a Subject
) get the newest data automatically.
In ngOnDestroy
we unsubscribe. If the component will destroyed we don't wanna updates any more (Memory Leaks or multiple subscritpion calls).
A very much bigger Project with this schema is here on Stackblitz. But the principle is the same - is always the same way.