Reputation: 85
I'm getting this exception when I'm trying to do this - messages.component.html:
<div *ngFor = "let message of messages | async">
<div *ngIf = "needToPrint(message.timestamp | date: 'dd/MM/yy')">
<p class = "date-stamp"> {{ message.timestamp | date: "MM/dd/yy" }} </p>
</div>
.
.
</div>
needToPrint function - messages.component.ts:
import { AfterViewChecked, ElementRef, ViewChild, Component, OnInit } from '@angular/core';
import { FirebaseListObservable } from 'angularfire2';
import { AF } from "../../providers/af";
import { ChangeDetectorRef } from "@angular/core";
@Component({
//selector: 'app-messages',
templateUrl: './messages.component.html',
styleUrls: ['./messages.component.css']
})
export class MessagesComponent implements OnInit, AfterViewChecked
{
@ViewChild('scrollMe') private myScrollContainer: ElementRef;
savedDate: string = '';
/* some code... */
// ==================================================
constructor(public afService: AF, private cdRef:ChangeDetectorRef)
{
this.messages = this.afService.messages;
}
// ==================================================
// If need to print the date ahead
needToPrint(date)
{
if (this.savedDate != date)
{
this.savedDate = date;
return true;
}
return false;
}
sendMessage()
{
this.afService.sendMessage(this.newMessage);
this.newMessage = '';
}
// ==================================================
ngAfterViewChecked()
{
// this.scrollToBottom();
}
scrollToBottom(): void
{
try {
this.myScrollContainer.nativeElement.scrollTop = this.myScrollContainer.nativeElement.scrollHeight;
} catch(err) { }
}
}
I understand that this exception is appear only in dev mode but how can I fix it? (I tried to read about this but still, no succeed to fix it).
thanks.
Upvotes: 1
Views: 1543
Reputation: 73337
Not tested, but hopefully this helps.
So as mentioned, the error is caused by calling a function in template, i.e
needToPrint(message.timestamp | date: 'dd/MM/yy')
I strongly suggest that you would refactor your code as such that you are not calling a function from the template, it is considered bad practice for change detection reasons, and in worse case it can cause an infinite loop: *ngFor running an infinite loop in angular2
The workaround for this though, could be invoking change detection manually, by using ChangeDetectorRef
. Import it, inject in constructor and use it inside needToPrint
-function:
import { ChangeDetectorRef } from '@angular/core';
constructor(private ref: ChangeDetectorRef) { }
needToPrint(date) {
if (this.savedDate != date){
this.savedDate = date;
this.ref.detectChanges();
return true;
}
this.ref.detectChanges();
return false;
}
Upvotes: 1