Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to avoid the view from flickering after list update in Ionic 3?

I'm new to Ionic 3 and firebase, and I'm trying to do a chat feature. My problem is when I update the array with new values, the whole list on view seems to flicker/blink. Is there a way to prevent this? Do I need to change my code?

Code(user-chat.ts)

getChats(){  
//Add by index idea to avoid blinking?
this.chatObserver = this.db.list('chat', ref => ref.child(this.authKey).orderByChild('timestamp'))
  .snapshotChanges().subscribe( snapshot => {
    let reversedSnap = snapshot.slice().reverse();
    let chatArray = [];
    reversedSnap.forEach( element =>{
      let data = element.payload.val();
      data['id'] = element.key;

      this.db.list('profile', ref=> ref.child(data['receiver'])).query.once('value', profileSnap => {
          let profileData = profileSnap.val();
          data['firstName'] = profileData.firstName;
          data['lastName'] = profileData.lastName;
          data['userImage'] = profileData.photos[0];
          data['userKey'] = profileSnap.key;
      })
      this.db.list('messages', ref=> ref.child(this.authKey).child(data['id']).orderByChild('timestamp').limitToLast(1))
        .query.once('value', messageSnap =>{
          messageSnap.forEach( element =>{  //only returns one, foreach to include checking if got 1
            let messageData = element.val();
            Object.assign(data, messageData);
            let message = ((data['sender'] === this.authKey)? "You: " : (data['firstName']+": "))+data['message'];
            data['message'] = (message.length>25 ? message.substring(0, 25)+"..." : message);
            data['messageDate'] = this.messageDateFormat(data['timestamp']);
          });
        chatArray.push(data);  
      });
    });
    this.chatList = chatArray;
  });
}

View(user-chat.html)

<ion-item-sliding *ngFor="let chat of chatList" >
            <button ion-item no-lines class="chat_content" (click)="openChat(chat.id, chat.receiver)">
                    <img class="circle-pic" src="{{chat.userImage}}" item-start>
                <h2 class="content">{{chat.firstName}} {{chat.lastName}}</h2>
                <p class="content">
                    <b *ngIf="!chat.isRead">{{chat.message}}</b>
                    <span *ngIf="chat.isRead">{{chat.message}}</span>~ {{chat.messageDate}}</p>
            </button>
            <ion-item-options side="left">
              <button ion-button no-lines ion-button class="chat_buttons" color="secondary" (click)="favorite(item)">
                <ion-icon class="chat_icons" name="star"></ion-icon>
              </button>
              <button ion-button class="chat_buttons" (click)="unread(item)">
                <ion-icon class="chat_icons" name="disc"></ion-icon>
              </button>
            </ion-item-options>

            <ion-item-options side="right">
              <button ion-button no-lines class="chat_buttons" color="danger" (click)="share(item)">
                <ion-icon class="chat_icons" name="trash"></ion-icon>
              </button>
            </ion-item-options>
        </ion-item-sliding>

What I expect is a result like in the facebook messenger app wherein the latest conversation is put on top and only slides the other conversation down.

Code retrieving data Code for view

like image 317
Luwelle Avatar asked Jan 28 '19 09:01

Luwelle


2 Answers

I faced this similar issue. I was able to fix this by adding trackBy in my *ngFor. https://angular.io/api/core/TrackByFunction

<ion-list *ngFor="let item of itemsList; trackBy: trackByFn">...</ion-list>

and in ts file:

 trackByFn(index: number, item: any): number {
   return item.serialNumber;
}
like image 65
Divya Avatar answered Sep 19 '22 14:09

Divya


This line is causing the list to blink this.chatList = chatArray;

This line is replacing the entire variable. That causes Angular to think that the entire data has been changed and hence it reloads. What you can try doing, is pushing the last element into this.chatList.

So instead of chatArray.push(data); try doing this.chatList.push(data).

Read up on Angular Change Detection.

like image 44
Delwyn Pinto Avatar answered Sep 19 '22 14:09

Delwyn Pinto