I am using angular 6 to develop my email application, I have a list of mail boxes for users who can click on the link to go to each mail box.
However, when I use component version A
to render the list, nothing will happen when click on the router link (no route will be triggered). But version B
works as expected. Both version A
and version B
render the UI properly. I wonder what is happening under the hood, it this is the correct behaviour of getter accessor? Or this is a bug of angular?
Angular version: 6.1.8
Browser: Chrome (desktop) version 69
Node version: v10.7.0
Platform: Mac
import { Component } from '@angular/core';
import { EmailService } from '~/email/services/email.service';
@Component({
templateUrl: '../views/email.view.html',
})
export class EmailComponent {
public constructor(private emailService: EmailService) {}
public get mailboxes(): Mailbox[] {
return this.emailService.mailboxes;
}
}
import { Component, OnInit } from '@angular/core';
import { EmailService } from '~/email/services/email.service';
@Component({
templateUrl: '../views/email.view.html',
})
export class EmailComponent implements OnInit {
public mailboxes: Mailbox[];
public constructor(private emailService: EmailService) {}
public async ngOnInit(): Promise<void> {
this.mailboxes = this.emailService.mailboxes;
}
}
@Injectable()
export class EmailService {
public get mailboxes(): Mailbox[] {
return [
{ name: 'Inbox', icon: 'inbox', link: 'inbox' },
{ name: 'Sent', icon: 'send', link: 'sent' },
{ name: 'Drafts', icon: 'drafts', link: 'drafts' },
{ name: 'Spam', icon: 'report', link: 'spam' },
{ name: 'Trash', icon: 'delete', link: 'trash' },
{ name: 'Archive', icon: 'archive', link: 'archive' },
];
}
}
<mat-nav-list>
<a mat-list-item *ngFor="let mailbox of mailboxes"
[routerLink]="['mailboxes', mailbox.link]">
<mat-icon matListIcon>{{mailbox.icon}}</mat-icon>
<h4 matLine>{{mailbox.name}}</h4>
</a>
</mat-nav-list>
demo link: https://stackblitz.com/edit/angular-gitter-clsw1d
Could seem strange at the beginning, but here you are linking 2 getter together and in your service you always return a new Array, so when angular is doing is checking to see if value change it start to go in some infinite loop because values at "never fix" since your array always change reference (this is not the case in the first way you do it). Try to change your service by :
@Injectable()
export class EmailService {
mailbox = [
{ name: 'Inbox', icon: 'inbox', link: 'inbox' },
{ name: 'Sent', icon: 'send', link: 'sent' },
{ name: 'Drafts', icon: 'drafts', link: 'drafts' },
{ name: 'Spam', icon: 'report', link: 'spam' },
{ name: 'Trash', icon: 'delete', link: 'trash' },
{ name: 'Archive', icon: 'archive', link: 'archive' },
];
public get mailboxes(): Mailbox[] {
return this.mailbox;
}
}
And it will work as expected.