ngx-pagination broke whenever I am passing new data to child component

1.2k Views Asked by At

I am using ngx-pagination package for pagination of large list. I am using pagination pipe inside the template of child component.

When ever the child component receives new Data pagination controls will broke and it won't work.

but if I restart the app it works properly Pagination broke only when I request new data and pass it to child component as input property.

I messed with pagination controls component properties. I have also tried setting the total items in paginate pipe. I have also tried setting pagination controls a Id and passed it into paginate pipe. But above tries didn't work at all.

Please find the child code below.

component.ts

export class AgentUserConvComponent implements OnChanges {

  @Input() chatData: Conversation[] = [];
  @Input() searchText: string;
  @Input() country: string;
  @Output() sendIds = new EventEmitter<MessagesToBeReviewed[]>();
  listLoading = true;
  msgsToBeReviewed: MessagesToBeReviewed[] = [];
  messages: Array<Message> = [];
  user = this.cookieService.getCookie('email').split('@')[0].length > 0 ? this.cookieService.getCookie('email').split('@')[0] : 'vijay.rm';

  constructor(private socketService: SocketService, private cookieService: CookieService) {}

  ngOnChanges() {

  }

  getConverse(chat: Conversation) {
    this.messages = chat.conversation;
    this.socketService.getRealtimeUsers();
  }

  updateMsgIds(id: number, user: string) {
    this.msgsToBeReviewed = [...this.msgsToBeReviewed, {id, user}];
    console.log('messagesToBeReviewed', this.msgsToBeReviewed);
  }
  checkInReviewMsgs(id: number, user: string) {
    return this.msgsToBeReviewed.filter(msg => msg.id === id).length > 0;
  }
  reviewIds(chat: Conversation) {
    this.sendIds.emit(this.msgsToBeReviewed);
    this.msgsToBeReviewed = [];
    this.socketService.userClosedConversation();
  }

  reviewAll(chat: Conversation) {
    const ids = chat.getMsgIdsAll();
    console.log('messageId for review all', ids);
    this.sendIds.emit(ids);
    this.msgsToBeReviewed = [];
    this.socketService.userClosedConversation();
  }

  afterExpand(chat: Conversation) {
    // tslint:disable-next-line: max-line-length
    this.socketService.userOpenedConversation({mlUser: this.user, user: chat.user, ids: chat.getMsgIdsAll().map(msg => msg.id), country: this.country});
  }
}

component.html

<h1 *ngIf="chatData.length === 0">No Conversations Yet</h1>
<mat-accordion *ngIf="chatData.length > 0">
  <mat-expansion-panel
    (closed)="reviewIds(chat)"
    (opened)="getConverse(chat)"
    (afterExpand)="afterExpand(chat)"
    *ngFor="
      let chat of chatData
        | search: searchText
        | paginate: { itemsPerPage: 15, currentPage: p, id: 'paginate' }
    "
  >
    <mat-expansion-panel-header>
      <mat-panel-title>
        <div class="title-style">
          <h4>{{ chat.user }}</h4>
          <span class="occupy-empty-space"></span>
          <div class="active-users">
            <ng-container
              *ngIf="!chat.reviewed && chat.getReviewers().length > 0"
            >
              <div *ngFor="let reviewer of chat.getReviewers()">
                <div class="circle-dot-user" [matTooltip]="reviewer">
                  <span
                    >{{ reviewer.split(".")[0][0].toUpperCase()
                    }}{{ reviewer.split(".")[1][0].toUpperCase() }}</span
                  >
                </div>
              </div>
            </ng-container>
          </div>
        </div>
      </mat-panel-title>
    </mat-expansion-panel-header>
    <mat-divider></mat-divider>

    <main
      class="msger-chat"
      *ngFor="let message of messages"
      class="expansion-class"
    >
      <div class="msg left-msg" *ngIf="message.req.length > 0">
        <div
          class="msg-img"
          style="background-image: url('static/distML/assets/image/user.svg')"
        ></div>
        <div class="msg-bubble">
          <div class="msg-info">
            <div class="msg-info-name">{{ message.id }}</div>
            <div class="msg-info-time">
              {{ message.time | date: "dd/MMM/yyyy, HH:mm a" }}
            </div>
          </div>
          <div class="msg-text">
            {{ message.req }}
          </div>
        </div>
      </div>

      <div class="msg right-msg" *ngIf="message.res">
        <div
          class="msg-img"
          style="background-image: url('static/distML/assets/image/favicon.512x512.png'); background-size: 55px 55px;"
        ></div>
        <div
          class="msg-bubble"
          [ngClass]="{
            'msg-bubble-default': !checkInReviewMsgs(message.msgId, message.id),
            'msg-bubble-addedToReview': checkInReviewMsgs(
              message.msgId,
              message.id
            ),
            'msg-bubble-reviewed': message.IsReviewed
          }"
        >
          <div class="msg-info">
            <div class="msg-info-name">Bot</div>
            <div class="msg-info-time">
              {{ message.time | date: "dd/MMM/yyyy, HH:mm a" }}
              <span
                *ngIf="
                  message.priority === null || message.priority.length <= 0
                "
                class="circleDot"
                >0</span
              >
              <span *ngIf="message.priority != null" class="circleDot">{{
                message.priority
              }}</span>
            </div>
          </div>
          <div
            class="msg-text"
            [innerHTML]="message.res | bypassSanitization: 'html'"
          >
            {{ message.res }}
          </div>
          <div class="msg-info-name" style="margin-top: 5px">
            <button
              *ngIf="!message.IsReviewed"
              mat-flat-button
              class="add-to-review"
              (click)="updateMsgIds(message.msgId, message.id)"
            >
              <div class="button-style">
                <p>
                  {{
                    checkInReviewMsgs(message.msgId, message.id)
                      ? "Added to Review"
                      : "Add to Review"
                  }}
                </p>
                <span class="occupy-empty-space"></span>
                <div class="active-users">
                  <ng-container *ngIf="message.reviewers.length > 0">
                    <div *ngFor="let reviewer of message.reviewers">
                      <div
                        class="circle-dot-user-button"
                        [matTooltip]="reviewer"
                      >
                        <span
                          >{{ reviewer.split(".")[0][0].toUpperCase()
                          }}{{ reviewer.split(".")[1][0].toUpperCase() }}</span
                        >
                      </div>
                    </div>
                  </ng-container>
                </div>
              </div>
            </button>
            <mat-chip-list *ngIf="message.IsReviewed">
              <mat-chip
                color="primary"
                selected
                [matTooltip]="message.ReviewedBy.split('@')[0]"
              >
                Reviewed by
                {{
                  message.ReviewedBy.split(".")[0][0].toUpperCase() +
                    message.ReviewedBy.split(".")[1][0].toUpperCase()
                }}
              </mat-chip>
            </mat-chip-list>
          </div>
        </div>
      </div>
    </main>
    <div class="msg-overflow"></div>
    <mat-action-row *ngIf="!chat.reviewed">
      <button mat-button color="accent" (click)="reviewAll(chat)">
        Review All
      </button>
    </mat-action-row>
  </mat-expansion-panel>
</mat-accordion>

<pagination-controls
  id="paginate"
  autoHide="true"
  responsive="true"
  (pageChange)="p = $event"
  class="pageControls"
  *ngIf="chatData.length > 0"
></pagination-controls>

When New data passed to child component paginate control component should work properly as it worked when the app is initialized.

1

There are 1 best solutions below

1
On BEST ANSWER

I am able to solve the issue. In my case I reused child component two times. I Used pagination controls inside child component. But the issue here is the pagination control is same instance where ever I am using the child component. And pagination controls component udate the UI with the last data it rececvied. Example: I have a reusable component. I am using this reusable component with two times inside two tabs. When ever I pass the data to this reusable components the data which rececevies last update the pagination controls component in all all places where ever I use the reausable component.Please check the solution I implemented.

<h1 *ngIf="chatData.length === 0">No Conversations Yet</h1>
<mat-accordion *ngIf="chatData.length > 0">
  <mat-expansion-panel
    (closed)="reviewIds(chat)"
    (opened)="getConverse(chat)"
    (afterExpand)="afterExpand(chat)"
    *ngFor="
      let chat of chatData
        | search: searchText
        | paginate: { itemsPerPage: 15, currentPage: isYetToBeReviewed ? p1 : p2, id: isYetToBeReviewed ? 'paginate1' : 'paginate2' }
    "
  >
    <mat-expansion-panel-header>
      <mat-panel-title>
        <div class="title-style">
          <h4>{{ chat.user }}</h4>
          <span class="occupy-empty-space"></span>
          <div class="active-users">
            <ng-container
              *ngIf="!chat.reviewed && chat.getReviewers().length > 0"
            >
              <div *ngFor="let reviewer of chat.getReviewers()">
                <div class="circle-dot-user" [matTooltip]="reviewer">
                  <span
                    >{{ reviewer.split(".")[0][0].toUpperCase()
                    }}{{ reviewer.split(".")[1][0].toUpperCase() }}</span
                  >
                </div>
              </div>
            </ng-container>
          </div>
        </div>
      </mat-panel-title>
    </mat-expansion-panel-header>
    <mat-divider></mat-divider>

    <main
      class="msger-chat"
      *ngFor="let message of messages"
      class="expansion-class"
    >
      <div class="msg left-msg" *ngIf="message.req.length > 0">
        <div
          class="msg-img"
          style="background-image: url('static/distML/assets/image/user.svg')"
        ></div>
        <div class="msg-bubble">
          <div class="msg-info">
            <div class="msg-info-name">{{ message.id }}</div>
            <div class="msg-info-time">
              {{ message.time | date: "dd/MMM/yyyy, HH:mm a" }}
            </div>
          </div>
          <div class="msg-text">
            {{ message.req }}
          </div>
        </div>
      </div>

      <div class="msg right-msg" *ngIf="message.res">
        <div
          class="msg-img"
          style="background-image: url('static/distML/assets/image/favicon.512x512.png'); background-size: 55px 55px;"
        ></div>
        <div
          class="msg-bubble"
          [ngClass]="{
            'msg-bubble-default': !checkInReviewMsgs(message.msgId, message.id),
            'msg-bubble-addedToReview': checkInReviewMsgs(
              message.msgId,
              message.id
            ),
            'msg-bubble-reviewed': message.IsReviewed
          }"
        >
          <div class="msg-info">
            <div class="msg-info-name">Bot</div>
            <div class="msg-info-time">
              {{ message.time | date: "dd/MMM/yyyy, HH:mm a" }}
              <span
                *ngIf="
                  message.priority === null || message.priority.length <= 0
                "
                class="circleDot"
                >0</span
              >
              <span *ngIf="message.priority != null" class="circleDot">{{
                message.priority
              }}</span>
            </div>
          </div>
          <div
            class="msg-text"
            [innerHTML]="message.res | bypassSanitization: 'html'"
          >
            {{ message.res }}
          </div>
          <div class="msg-info-name" style="margin-top: 5px">
            <button
              *ngIf="!message.IsReviewed"
              mat-flat-button
              class="add-to-review"
              (click)="updateMsgIds(message.msgId, message.id)"
            >
              <div class="button-style">
                <p>
                  {{
                    checkInReviewMsgs(message.msgId, message.id)
                      ? "Added to Review"
                      : "Add to Review"
                  }}
                </p>
                <span class="occupy-empty-space"></span>
                <div class="active-users">
                  <ng-container *ngIf="message.reviewers.length > 0">
                    <div *ngFor="let reviewer of message.reviewers">
                      <div
                        class="circle-dot-user-button"
                        [matTooltip]="reviewer"
                      >
                        <span
                          >{{ reviewer.split(".")[0][0].toUpperCase()
                          }}{{ reviewer.split(".")[1][0].toUpperCase() }}</span
                        >
                      </div>
                    </div>
                  </ng-container>
                </div>
              </div>
            </button>
            <mat-chip-list *ngIf="message.IsReviewed">
              <mat-chip
                color="primary"
                selected
                [matTooltip]="message.ReviewedBy.split('@')[0]"
              >
                Reviewed by
                {{
                  message.ReviewedBy.split(".")[0][0].toUpperCase() +
                    message.ReviewedBy.split(".")[1][0].toUpperCase()
                }}
              </mat-chip>
            </mat-chip-list>
          </div>
        </div>
      </div>
    </main>
    <div class="msg-overflow"></div>
    <mat-action-row *ngIf="!chat.reviewed">
      <button mat-button color="accent" (click)="reviewAll(chat)">
        Review All
      </button>
    </mat-action-row>
  </mat-expansion-panel>
</mat-accordion>

<div *ngIf="chatData.length > 0">
  <pagination-controls
  id="paginate1"
  autoHide="true"
  responsive="true"
  (pageChange)="p1 = $event"
  class="pageControls"
  *ngIf="isYetToBeReviewed"
></pagination-controls>
</div>
<div *ngIf="chatData.length > 0">
  <pagination-controls
  id="paginate2"
  autoHide="true"
  responsive="true"
  (pageChange)="p2 = $event"
  class="pageControls"
  *ngIf="!isYetToBeReviewed"
></pagination-controls>
</div>