I have an Angular7 app and I'm choosing to display a button in app.component based on a boolean that's defined as:
get superUser(): boolean {
return this.auth.userPermissions.SUPER_USER;
}
Now in my auth service, I have the userPermissions initialized after the Permissions model with all permissions marked as 'false'.
permissions: Permissions = {
SUPER_USER: false,
CLIENT_ADMIN: true,
ADD_CLIENT: false,
ADD_USER: false,
DELETE_CLIENT: false,
DELETE_USER: false,
READ_ALL_CLIENTS: false,
READ_ALL_USERS: false,
READ_REPORTS: false,
READ_USERS: false,
UPDATE_CLIENT: false
};
public get userPermissions(): Permissions {
return this.permissions;
}
On Authentication, the permissions array is sent to the reducer and permissions are being set with ngrx store.
.subscribe((token: string) => {
Cookie.set('access_token', token);
this.store.dispatch(new UserActions.SetUser(this.currentUser));
const currentUser = this.helper.decodeToken(token);
this.store.dispatch(
new PermissionsActions.SetPermissions(currentUser.permissions)
);
return this.router.navigate(['']);
});
In the service, I'm subscribing to that store value and updating the permissions object.
this.permissionSubscription = this.store
.select('permissions')
.subscribe(permissions => {
this.permissions = permissions;
});
Now the trouble is, the very first time after authentication the whole thing crashes returning:
Cannot read property 'SUPER_USER' of undefined
Referencing the line where I defined the getter.
But it is defined everywhere. There's not a place in my code I haven't initialized and defined the model variable with the 'false' default.
In my reducer that processes the array of permissions:
const keys: string[] = Object.keys(state);
for (const permission of action.permissions) {
if (keys.includes(permission.name)) {
state[permission.name] = true;
} else {
return console.log('ELSE BLOCK FIRING');
}
}
return tassign(state);
It seems that I forgot to update the model with permissions that were in that array and when the for loop got to that, it made the whole state undefined.
Ended up being reducer shenanigans where a function was trying to do something with a property that didn't exist, messing up the whole object onInit every time.