In a previous question here, I am trying to show a date only when it has changed between 2 messages.
The difference is that I am now connected to a realtime database (Firebase), so I subscribe to the data source and pass it through the async pipe before going through index and *ngIf:
<div *ngFor='let message of (chat | async) ; let i = index'>
<button *ngIf="i == 0 || (message.timestamp | date: 'ddMMMMyyyy') != ((chat | async)[i-1].timestamp | date: 'ddMMMMyyyy')">
{{ message.timestamp | date:'ddMMM' }}
</button>
...
<!--More html elements below (omitted)-->
...
</div>
This works well when I first load the view, however, if I push a new entry into chat
, I get the following error:
TypeError: Cannot read property '0' of null
Maybe I am not too sure how the async pipe works, but when I try returning {{ (chat | async).length }}
, it works as intended. Any suggestions on a workaround/proper practice?
In case someone else finds this since it's the first result with the key words, I was able to get the index of a *ngFor with the async pipe like this (assuming messages
is an Observable of an iterable):
<div *ngFor="let message of (messages | async); let i = index;">
Still not sure how the AsyncPipe can be manipulated here, but I did mange to find a workaround that involves not using the pipe. I will await a better answer hopefully before marking this closed.
I subscribe to the data source in my class, and manipulate the array with a for loop before displaying it.
The (template) code in my question has now become:
<div *ngFor='let message of messages; let i = index'>
<button *ngIf="message.isNewDay">
{{ message.timestamp | date:'ddMMM' }}
</button>
...
<!--More html elements below (omitted)-->
...
</div>
And in the controller:
private chatid: string //chat id passed from previous screen
private chat: FirebaseListObservable<any>;
private messages: any = [];
constructor(private firebase: FirebaseService,
private _datepipe: DatePipe) {
}
ionViewLoaded() {
this.chat = this.firebase.database.list('/chat-messages/' + this.chatid);
this.chat.subscribe((data) => {
this.messages = data;
for (let i: number = 0; i < this.messages.length; i++) {
if (i === 0)
this.messages[i].isNewDay = true;
else {
let date1 = this._datepipe.transform(this.messages[i].timestamp, 'ddMMMMyyyy');
let date2 = this._datepipe.transform(this.messages[i-1].timestamp, 'ddMMMMyyyy');
if (date1 !== date2)
this.messages[i].isNewDay = true;
else
this.messages[i].isNewDay = false;
}
}
});
}
Note that I am currently using DatePipe in the class code (as well as in the template), so it is necessary to use providers: [DatePipe]
along with pipes: [DatePipe]
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With