I am new to Angular so I wouldnt be surprised that I am missing basic things. I tried Angular docs and googling, but no clue so far of why my component just updates the UI after a click?
My scenario is, I want to have a shared component called NotificationComponent with a shared service called NotificationService. Since I can have more then 1 error happening, my NotificationComponent should display all of these messages . On top of that I have an http error interceptor and a custom error handling.
What is happening is, I get 3 https errors, interceptor is getting all 3, custom error handling is handling all 3, notification service is creating all 3 errors but notification component is rendering only 1 (sometimes 2) errors automatically. Once I click anywhere in the UI, the reminding msgs shows up. Why is that happening?
Hierarchy: AppModule
imports SharedModule
[contains notification service and component]. Notification component selector is inside app.component.html
Component:
@Component({
selector: 'app-notification',
templateUrl: './notification.component.html',
styleUrls: ['./notification.component.scss']
})
export class NotificationComponent implements OnInit, OnDestroy {
messages: Message[] = [];
notificationSubscription: Subscription;
constructor(private notificationService: NotificationService) { }
ngOnInit() {
this.notificationSubscription = this.notificationService.onNotify()
.subscribe(msg => {
this.messages.push(msg);
});
}
ngOnDestroy() {
// unsubscribe to avoid memory leaks
this.notificationSubscription.unsubscribe();
}
}
HTML:
<div *ngFor = "let msg of messages" role="alert">
{{msg.detail}}
</div>
Service:
@Injectable({
providedIn: 'root'
})
export class NotificationService {
messages: Message[];
private subject = new Subject<Message>();
constructor() {
this.messages = [];
}
onNotify(): Observable<Message> {
return this.subject.asObservable();
}
error(title: string, detail: string): void {
this.notify({type: 'error', title: title, detail: detail});
}
notify(message: Message) {
this.subject.next(message);
}
}
Custom Error Handler:
@Injectable()
export class CustomErrorHandler implements ErrorHandler {
constructor(@Inject(NotificationService)
private notificationService: NotificationService) {
}
handleError(error: any): void {
this.notificationService.error(error.title, error.detail);
}
}
PS: I am not restricted to any particular implementation, so I can change the approach if needed.