I have the following SessionService.component.ts
with a logout()
method:
@Injectable({ providedIn: 'root' })
export class SessionService {
constructor() {}
// other session service stuff
logout() {
console.log('SessionService.logout');
// do logout stuff
}
}
The following MenuComponent.component.ts
creates the menu content of the app
import { SessionService } from '../session/session.service';
@Component({
selector: 'app-menu',
templateUrl: './menu.component.html',
styleUrls: ['./menu.component.css']
})
export class MenuComponent implements OnInit {
menuItems: Array<any>;
constructor(private sessionService: SessionService) {}
ngOnInit() {
menuItems = [
// logout menu item
{
name: 'Logout',
action: this.signout
}
];
}
// method called 'signout' to make it clear what method is called when
signout() {
console.log('MenuComponent.signout');
this.sessionService.logout();
}
}
Lastly, the HTML template MenuComponent.component.html
looks like this:
<mat-accordion class="example-headers-align" multi hideToggle displayMode="flat">
<!-- App Signout -->
<!-- THIS WORKS when (click)="signout()" is called -->
<mat-expansion-panel class="menu-section mat-elevation-z0">
<mat-expansion-panel-header (click)="signout()">
<mat-panel-title fxLayout="row" fxLayoutAlign="start center">
<mat-icon class="menu-section-icon" svgIcon="logout"></mat-icon>
<span class="menu-section-title" tts="Logout"></span>
</mat-panel-title>
</mat-expansion-panel-header>
</mat-expansion-panel>
<!-- Menu Items inside ngFor loop -->
<!-- (click)="menuItem.action()" fails with the error described below, after this code block -->
<mat-expansion-panel class="menu-section mat-elevation-z0" *ngFor="let menuItem of menuItems">
<mat-expansion-panel-header (click)="menuItem.action()">
<mat-panel-title fxLayout="row" fxLayoutAlign="start center">
<span class="menu-section-title">{{ menuItem.name }}</span>
</mat-panel-title>
</mat-expansion-panel-header>
</mat-accordion>
When I explicitly call the function signout()
from the template, I get the expected console output which is
console.log('MenuComponent.signout');
console.log('SessionService.logout');
However, when selecting the menu item from the array, the session service is undefined and the SessionService.logout()
function is never executed. I get the error
core.js:4442 ERROR TypeError: Cannot read property 'logout' of undefined at Object.signout [as action] (menu.component.ts:195) at MenuComponent_mat_expansion_panel_9_Template_mat_expansion_panel_header_click_1_listener (menu.component.html:38) at executeListenerWithErrorHandling (core.js:15225) at wrapListenerIn_markDirtyAndPreventDefault (core.js:15266) at HTMLElement. (platform-browser.js:582) at ZoneDelegate.invokeTask (zone-evergreen.js:402) at Object.onInvokeTask (core.js:27492) at ZoneDelegate.invokeTask (zone-evergreen.js:401) at Zone.runTask (zone-evergreen.js:174) at ZoneTask.invokeTask [as invoke] (zone-evergreen.js:483)
I presume it has something to do with the scope or initialisation sequence of all the components, but for the life of me I can't figure out what I need to change...
Thank you in advance :-)