I'm using Laravel as REST API.
My frontend should show
All Permission
All Roles
All Roles with their specific Permissions
My Errors (F12)
(11) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
installHook.js:1 ERROR RuntimeError: NG0100: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'undefined'. Current value: 'can_accessDashboard'. Expression location: _Dashboard component It seems like the view has been created after its parent and its children have been dirty checked. Has it been created in a change detection hook? Find more at https://v21.angular.dev/errors/NG0100
at Dashboard_For_12_Template (component?c=src%2Fap…1770823049874:27:19)
dashboard.ts:46
(4) [{…}, {…}, {…}, {…}]
installHook.js:1 ERROR RuntimeError: NG0100: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'undefined'. Current value: 'Developer'. Expression location: _Dashboard component It seems like the view has been created after its parent and its children have been dirty checked. Has it been created in a change detection hook? Find more at https://v21.angular.dev/errors/NG0100
at Dashboard_For_8_Template (component?c=src%2Fap…1770823049874:15:19)
dashboard.ts:56
{roles: Array(4)}
installHook.js:1 ERROR RuntimeError: NG0100: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'undefined'. Current value: 'Developer'. Expression location: _Dashboard component It seems like the view has been created after its parent and its children have been dirty checked. Has it been created in a change detection hook? Find more at https://v21.angular.dev/errors/NG0100
at Dashboard_For_8_Template (component?c=src%2Fap…1770823049874:15:19)
Stack:
Angular v21
Laravel v12
Sanctum
Spatie for Permission and Role System
Placeholder data
Backend sends data correctly, for example:
0 : {id: 1, name: 'permission', guard_name: 'web', created_at: '2026-02-11T14:02:10.000000Z', updated_at: '2026-02-11T14:02:10.000000Z'}
My Files:
FRONTEND
permissionRoleDatabase
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { environment } from '../../../../../environments/environment';
@Injectable({
providedIn: 'root',
})
export class PermissionRoleDatabase {
constructor(
private http: HttpClient
) {}
public getAllPermissions(): Observable<any> {
const url = environment.apiURL + '/getAllPermissions';
return this.http.get(url);
}
public getAllRoles(): Observable<any> {
const url = environment.apiURL + '/getAllRoles';
return this.http.get(url);
}
public getUserPermissions(): Observable<any> {
const url = environment.apiURL + '/getUserPermissions';
return this.http.get(url);
}
public getAllRolesWithPermissions(): Observable<any> {
const url = environment.apiURL + '/getAllRolesWithPermissions';
return this.http.get(url);
}
}
dashboard.ts
import { Component, inject, PLATFORM_ID } from '@angular/core';
import { MatTabsModule } from '@angular/material/tabs';
import { PermissionRoleDatabase } from '../../shared/services/permission/database/permission.database';
import { permissionModel } from './models/allPermissions.model';
import { roleModel } from './models/allRoles.model';
import { rolePermissionModel } from './models/rolePermissions.model';
import { isPlatformBrowser } from '@angular/common';
@Component({
selector: 'app-dashboard',
imports: [MatTabsModule],
templateUrl: './dashboard.html',
styleUrl: './dashboard.scss',
})
export class Dashboard {
private permissionRoleDatabase = inject(PermissionRoleDatabase);
private platformId = inject(PLATFORM_ID);
protected allPermissions: permissionModel[] = [];
protected allRoles: roleModel[] = [];
protected rolePermissions: rolePermissionModel[] = [];
ngOnInit() {
if (!isPlatformBrowser(this.platformId)) return;
this.getAllPerms();
}
private getAllPerms(): void {
this.permissionRoleDatabase.getAllPermissions().subscribe({
next: (res) => {
this.allPermissions = res;
console.log(res);
},
error: (err) => {
console.error('Error getting Permissions', err);
},
});
this.permissionRoleDatabase.getAllRoles().subscribe({
next: (res) => {
this.allRoles = res;
console.log(res);
},
error: (err) => {
console.error('Error getting Roles', err);
},
});
this.permissionRoleDatabase.getAllRolesWithPermissions().subscribe({
next: (res) => {
this.rolePermissions = res;
console.log(res);
},
error: (err) => {
console.error('Error getting Roles with Permissions', err);
},
});
}
}
dashboard.html
<mat-tab-group>
<mat-tab label="Dashboard">
<div>
<p>i dunno lol</p>
</div>
</mat-tab>
<mat-tab label="User Management">
<div>
@for (data of allRoles; track data.id ) {
<li>
{{ data.name }}
</li>
}
</div>
</mat-tab>
<mat-tab label="Role Management">
<div>
@for (data of allPermissions; track data.id ) {
<li>
{{ data.name }}
</li>
}
</div>
</mat-tab>
</mat-tab-group>
What I've tried:
place my getAllPerms() into constructor.
Place my getAllPerms() into ngAfterContentInit.
Playe my getAllPerms() into a setTimeout.
setTimeout(() => { this.getAllPerms(); }, 0);
The data is shown correctly, but nevertheless the errors in my Console appear
Using ngAfterContentInit() instead of ngOnInit()