Im using role guards . A user can access certain routes only if user has certain rights. The user rights are fetched from backend using a service called login service inside app root component and is stored in a set inside a configuration service. The user rights are fetched from service when required.The problem is that my role guard also needs to fetch the user rights. Since my user rights are fetched inside app component,the role guard is getting executed before the user rights service response . Im forced to call data again from backend inside the role guard.Ideally i want the data to be fetched only once.How to go about this?
Inside app.component.ts:
loadUserOtherDetails() {
forkJoin([this.loginService.userRights(), this.loginService.mytenant()]).subscribe(data => {
this.onUserRightsReceived(data[0]);
this.onTenantDataReceived(data[1]);
});
}
onUserRightsReceived(userRights) {
this.confService.updateRights(userRights["rights"]);
}
}
Inside configuration service(confService):
public rights: Subject<Array<string>>;
updateRights(rights: Array<string>) {
this.rights.next(rights);
}
getRights() {
return this.rights.asObservable();
}
Inside role guard:
@Injectable()
export class RoleGuard implements CanActivate {
activate = false;
constructor(private loginService: LoginServiceService,
private router: Router,
private configService:ConfigurationService
) {
}
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<boolean> | boolean {
return this.confService.getRights().pipe(map((userRights) => {
console.log("rights",userRights)
this.configService.updateRights(userRights['rights']);
return this.filterUserRights(userRights['rights']);
}),
)
}
filterUserRights(userRights:Array<string>){
const requiredRights = ['create_organisation', 'create_tenant', 'create_user'];
if (requiredRights.some((right) => userRights && userRights.includes(right))) {
this.activate = true;
} else {
this.activate = false;
}
return this.activate;
}
}
This works when after user logs in first time. But if i refresh the page,the rights do not get stored in confservice first.
I created resolver :
import { Injectable } from '@angular/core';
import { Resolve } from '@angular/router';
import { LoginServiceService } from './login-service.service';
@Injectable()
export class RightsResolver implements Resolve<any> {
constructor(private loginService:LoginServiceService) {}
resolve() {
return this.loginService.userRights();
}
}
My routing:
const routes: Routes = [
{
path: "", redirectTo: "mylearning", pathMatch: "full", resolve: { rightsResolver: RightsResolver }
},
{
path: "managepeople",
component: ManagepeopleComponent,
canActivate: [RoleGuard],
children: [
{ path: "", redirectTo: "organisations", pathMatch: "full" },
{
path: "organisations",
component: OrganisationsComponent,
data: {
animation: "organisations"
}
},
{
path: "organisations/create",
component: OrganisationAddComponent,
data: {
breadcrumb: [
{
label: "Organisations ",
url: "organisations"
},
{
label: "Add",
url: ""
}
]
}
},
{
path: "organisation-edit/:id",
component: OrganisationEditComponent,
data: {
breadcrumb: [
{
label: "Organisations ",
url: "organisations"
},
{
label: "{{orgName}} ",
url: "organisation-detail/:id"
},
{
label: "Edit",
url: ""
}
]
}
},
{
path: "organisation-detail/:id",
component: OrganisationDetailComponent,
data: {
breadcrumb: [
{
label: "Organisations ",
url: "organisations"
},
{
label: "{{orgName}}",
url: ""
}
]
},
children: [
{ path: "", component: OrgMainComponent },
{
path: "orgunits/:id",
component: OrganisationUnitsOfOrganisationComponent,
data: {
animation: "orgunitslist",
breadcrumb: [
{
label: "Organisations ",
url: "organisations"
},
{
label: "{{orgName}} ",
url: "organisation-detail/:id"
},
{
label: "Organisation Units ",
url: ""
}
]
}
},
{
path: "orgunits/:id/add",
component: OrganisationUnitsOfOrganisationAddComponent,
data: {
animation: "orgunitadd",
breadcrumb: [
{
label: "Organisations ",
url: "organisations"
},
{
label: "{{orgName}} ",
url: "organisation-detail/:id"
},
{
label: "Organisation Units ",
url: "organisation-detail/:id/orgunits/:id"
},
{
label: "Add ",
url: ""
}
]
}
},
{
path: "orgunits/:id/:orgUnit/edit",
component: OrganisationUnitsOfOrganisationEditComponent,
data: {
animation: "orgunitedit",
breadcrumb: [
{
label: "Organisations ",
url: "organisations"
},
{
label: "{{orgName}} ",
url: "organisation-detail/:id"
},
{
label: "Organisation Units ",
url: "organisation-detail/:id/orgunits/:id"
},
{
label: "Edit ",
url: ""
}
]
}
},
{
path: "users/:id",
component: UsersOfOrganisationComponent,
pathMatch: "full",
data: {
animation: "userslist",
breadcrumb: [
{
label: "Organisations ",
url: "organisations"
},
{
label: "{{orgName}} ",
url: "organisation-detail/:id"
},
{
label: "Users ",
url: ""
}
]
}
},
{
path: "users/:id/add",
component: UsersOfOrganisationAddComponent,
data: {
animation: "usertadd",
breadcrumb: [
{
label: "Organisations ",
url: "organisations"
},
{
label: "{{orgName}} ",
url: "organisation-detail/:id"
},
{
label: "Users ",
url: "organisation-detail/:id/users/:id"
},
{
label: "Add ",
url: ""
}
]
}
},
{
path: "users/:id/:user/edit",
component: UsersOfOrganisationEditComponent,
data: {
animation: "useredit",
breadcrumb: [
{
label: "Organisations ",
url: "organisations"
},
{
label: "{{orgName}} ",
url: "organisation-detail/:id"
},
{
label: "Users",
url: "organisation-detail/:id/users/:id"
},
{
label: "Edit ",
url: ""
}
]
}
},
{
path: "positions/:id",
component: PositionsOfOrganisationComponent,
data: {
animation: "positionslist",
breadcrumb: [
{
label: "Organisations ",
url: "organisations"
},
{
label: "{{orgName}} ",
url: "organisation-detail/:id"
},
{
label: "Positions",
url: ""
}
]
}
},
{
path: "positions/:id/add",
component: PositionsOfOrganisationAddComponent,
data: {
animation: "positionadd",
breadcrumb: [
{
label: "Organisations ",
url: "organisations"
},
{
label: "{{orgName}} ",
url: "organisation-detail/:id"
},
{
label: "Positions",
url: "organisation-detail/:id/positions/:id"
},
{
label: "Add ",
url: ""
}
]
}
},
{
path: "positions/:id/:position/edit",
component: PositionsOfOrganisationEditComponent,
data: {
animation: "positionedit",
breadcrumb: [
{
label: "Organisations ",
url: "organisations"
},
{
label: "{{orgName}} ",
url: "organisation-detail/:id"
},
{
label: "Positions",
url: "organisation-detail/:id/positions/:id"
},
{
label: "Edit ",
url: ""
}
]
}
},
{
path: "groups/:id",
component: GroupsOfOrganisationComponent,
data: {
animation: "groupslist",
breadcrumb: [
{
label: "Organisations ",
url: "organisations"
},
{
label: "{{orgName}} ",
url: "organisation-detail/:id"
},
{
label: "Groups",
url: ""
}
]
}
},
{
path: "groups/:id/add",
component: GroupsOfOrganisationAddComponent,
data: {
animation: "groupadd",
breadcrumb: [
{
label: "Organisations ",
url: "organisations"
},
{
label: "{{orgName}} ",
url: "organisation-detail/:id"
},
{
label: "Groups",
url: "organisation-detail/:id/groups/:id"
},
{
label: "Add ",
url: ""
}
]
}
},
{
path: "groups/:id/:group/edit",
component: GroupsOfOrganisationEditComponent,
data: {
animation: "useredit",
breadcrumb: [
{
label: "Organisations ",
url: "organisations"
},
{
label: "{{orgName}} ",
url: "organisation-detail/:id"
},
{
label: "Groups",
url: "organisation-detail/:id/groups/:id"
},
{
label: "Edit ",
url: ""
}
]
}
}
]
},
{
path: "organisation-units",
component: OrganisationUnitsComponent,
data: { animation: "orgUnits" }
},
{
path: "organisation-unit/create",
component: OrganisationUnitAddComponent,
data: {
breadcrumb: [
{
label: "Organisation Units ",
url: "organisation-units"
},
{
label: "Add",
url: ""
}
]
}
},
{
path: "organisation-unit-edit/:id",
component: OrganisationUnitEditComponent,
data: {
breadcrumb: [
{
label: "Organisation Units ",
url: "organisation-units"
},
{
label: "{{orgunitName}}",
url: "organisation-unit-detail/:id"
},
{
label: "Edit",
url: ""
}
]
}
},
{
path: "organisation-unit-detail/:id",
component: OrgUnitsDetailComponent,
data: {
breadcrumb: [
{
label: "Organisation Units ",
url: "organisation-units"
},
{
label: "{{orgunitName}}",
url: ""
}
]
},
children: [
{ path: "", component: OrgUnitMainComponent },
{
path: "positions/:id",
component: PositionsOfOrganisationunitComponent,
data: {
animation: "positionslist",
breadcrumb: [
{
label: "Organisation Units ",
url: "organisation-units"
},
{
label: "{{orgunitName}} ",
url: "organisation-unit-detail/:id"
},
{
label: "Positions",
url: ""
}
]
}
},
{
path: "positions/:id/add",
component: PositionsOfOrganisationunitAddComponent,
data: {
animation: "positionadd",
breadcrumb: [
{
label: "Organisation Units",
url: "organisation-units"
},
{
label: "{{orgunitName}} ",
url: "organisation-unit-detail/:id"
},
{
label: "Positions",
url: "organisation-unit-detail/:id/positions/:id"
},
{
label: "Add ",
url: ""
}
]
}
},
{
path: "positions/:id/:position/edit",
component: PositionsOfOrganisationunitEditComponent,
data: {
animation: "positionedit",
breadcrumb: [
{
label: "Organisation Units ",
url: "organisation-units"
},
{
label: "{{orgunitName}} ",
url: "organisation-unit-detail/:id"
},
{
label: "Positions",
url: "organisation-unit-detail/:id/positions/:id"
},
{
label: "Edit ",
url: ""
}
]
}
}
]
},
{
path: "positions",
component: PositionsComponent,
data: { animation: "positions" }
},
{
path: "positions/add",
component: PositionAddComponent,
data: {
animation: "positionsAdd",
breadcrumb: [
{
label: "Positions ",
url: "positions"
},
{
label: "Add",
url: ""
}
]
}
},
{
path: "positions/edit/:id",
component: PositionEditComponent,
data: {
animation: "positionEdit",
breadcrumb: [
{
label: "Positions ",
url: "positions"
},
{
label: "{{positionName}} ",
url: "position-detail/:id"
},
{
label: "Edit",
url: ""
}
]
}
},
{
path: "position-detail/:id",
component: PositionDetailComponent,
data: {
animation: "positionDetail",
breadcrumb: [
{
label: "Positions ",
url: "positions"
},
{
label: "{{positionName}}",
url: ""
}
]
},
children: [{ path: "", component: PositionDetailMainComponent }]
},
{
path: "position-classification",
component: PositionClassificationComponent,
data: { animation: "positionClassifications" }
},
{
path: "position-classification/add",
component: PositionClassificationAddComponent,
data: {
animation: "positionClassificationsAdd",
breadcrumb: [
{
label: "Position Classifications ",
url: "position-classification"
},
{
label: "Add",
url: ""
}
]
}
},
{
path: "position-classification-detail/:id",
component: PositionClassificationDetailComponent,
data: {
animation: "postionClassificationDetail",
breadcrumb: [
{
label: "Postion Classifications",
url: "position-classification"
},
{
label: "{{positionClassificationName}}",
url: ""
}
]
},
children: [{ path: "", component: PositionClassificationMainComponent }]
},
{
path: "position-classification/edit/:id",
component: PositionClassificationEditComponent,
data: {
animation: "positionClassificationEdit",
breadcrumb: [
{
label: "Postion Classifications",
url: "position-classification"
},
{
label: "{{positionClassificationName}} ",
url: "position-classification-detail/:id"
},
{
label: "Edit",
url: ""
}
]
}
},
{
path: "group-types",
component: GroupTypesComponent,
data: { animation: "groupTypes" }
},
{
path: "group-types/add",
component: GroupTypesAddComponent,
data: {
animation: "groupTypesAdd",
breadcrumb: [
{
label: "Group Types ",
url: "group-types"
},
{
label: "Add",
url: ""
}
]
}
},
{
path: "group-types/edit/:id",
component: GroupTypesEditComponent,
data: {
animation: "groupTypesEdit",
breadcrumb: [
{
label: "Group Types ",
url: "group-types"
},
{
label: "{{groupTypeName}} ",
url: "group-type-detail/:id"
},
{
label: "Edit",
url: ""
}
]
}
},
{
path: "group-type-detail/:id",
component: GroupTypeDetailComponent,
data: {
animation: "groupTypeDetail",
breadcrumb: [
{
label: "Group Types ",
url: "group-types"
},
{
label: "{{groupTypeName}}",
url: ""
}
]
},
children: [{ path: "", component: GroupTypeMainComponent }]
},
{
path: "groups",
component: GroupsComponent,
data: { animation: "groups" }
},
{
path: "groups/add",
component: GroupAddComponent,
data: {
animation: "group-add",
breadcrumb: [
{
label: "Groups",
url: "groups"
},
{
label: "Add",
url: ""
}
]
}
},
{
path: "group-detail/:id",
component: GroupDetailComponent,
data: {
animation: "group-detail",
breadcrumb: [
{
label: "Groups ",
url: "groups"
},
{
label: "{{groupName}}",
url: ""
}
]
},
children: [{ path: "", component: GroupMainComponent }]
},
{
path: "groups/edit/:id",
component: GroupEditComponent,
data: {
animation: "groupEdit",
breadcrumb: [
{
label: "Groups ",
url: "groups"
},
{
label: "{{groupName}} ",
url: "group-detail/:id"
},
{
label: "Edit",
url: ""
}
]
}
},
{
path: "users",
component: UsersComponent,
data: { animation: "users" }
},
{
path: "users/create",
component: UsersAddComponent,
data: {
breadcrumb: [
{
label: "Users ",
url: "users"
},
{
label: "Add",
url: ""
}
]
}
},
{
path: "user-edit/:id",
component: UserEditComponent,
data: {
breadcrumb: [
{
label: "Users ",
url: "users"
},
{
label: "{{userName}} ",
url: "user-detail/:id"
},
{
label: "Edit",
url: ""
}
]
}
},
{
path: "user-detail/:id",
component: UsersDetailComponent,
data: {
breadcrumb: [
{
label: "Users ",
url: "users"
},
{
label: "{{userName}}",
url: ""
}
]
}
}
]
},