ERROR TypeError: Cannot read properties of undefined (reading 'page')

Issue

Please I need some help with angular

I am trying to perform serverSide pagination integrate but no matter how many iterations of the code I come up with, I keep getting the same error:

ERROR TypeError: Cannot read properties of undefined (reading ‘page’)
at ListingsComponent.ngAfterViewInit (listings.component.ts:271)

I have changed my code numerous times because of this error. Here is the current iteration code:

HTML:

<ng-container *ngIf="listings$ | async as listings">
        <div class="col-lg-9">
        <div class="row align-items-center mb-4">
          <div class="col-md-6 col">
            <h4><span>{{listings.totalElements || listings.content.length }}</span> Services</h4>
          </div>
        </div>
        <div>
        
          <div class="row" >
            <div class="col-lg-4 col-md-6" *ngFor="let service of listings.content">
                <div class="service-widget">
                    <div class="service-img">
                        <a style="cursor: pointer;" (click)="routeToService(service.id)">
                            <img class="img-fluid serv-img" alt="Service Image" [src]="service.pictures ? service.pictures : 'https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__480.jpg'">
                        </a>
                        <div class="item-info">
                            <div class="service-user">
                                <a href="javascript:void(0);">
                                    <img src="assets/img/customer/user-01.jpg" alt="">
                                </a>
                                <span class="service-price">{{service.fixedPrice}}</span>
                            </div>
                            <div class="cate-list">
                                <a class="bg-yellow" style="cursor: pointer;" (click)="routeToService(service.id)" class="bg-yellow" >{{service.name}}</a>
                            </div>
                        </div>
                    </div>
                    <div class="service-content">
                        <h3 class="title text-truncate">
                            <a class="ellipsis" style="cursor: pointer;" (click)="routeToService(service.id)">{{service.detailedDescription}}</a>
                        </h3>
                        <div class="rating">
                            <i class="fas fa-star filled"></i>
                            <i class="fas fa-star filled"></i>
                            <i class="fas fa-star filled"></i>
                            <i class="fas fa-star filled"></i>
                            <i class="fas fa-star filled"></i>
                            <span class="d-inline-block average-rating">(4.3)</span>
                        </div>
                        <!-- <div class="user-info">
                            <div class="service-action">
                                <div class="row">
                                    <div class="col">
                                        <a [routerLink]="'/pages/edit-service'" class="text-success"><i class="far fa-edit"></i> Edit</a>
                                    </div>
                                    <div class="col text-right">
                                        <a href="javascript:void(0);" class="text-danger" data-toggle="modal" data-target="#deleteNotConfirmModal"><i class="far fa-trash-alt"></i> Inactive</a>
                                    </div>
                                </div>
                            </div>
                        </div> -->
                    </div>
                </div>
            </div>
            <div class="col-12">
          <mat-paginator [length]="listings.totalElements || listings.content.length " [pageSize]="pageSize" showFirstLastButtons>
          </mat-paginator>
            </div>
            
        </div>
        </div>
      </div>
       <!-- mat paginator goes here -->
          
      </ng-container>

TypeScript:

  listingDataSource: ListingsDataSource | null;

  pageNumber: number = 1;
  pageSize: number = 9;
  sortBy: string = 'dateCreated';
  sortOrder: string = 'DESCENDING';
  keyword: string = this.router.snapshot.queryParamMap.get('search') || '';

  listings$: Observable<any>;

ngAfterViewInit(): void {
 
    this.listingDataSource = new ListingsDataSource(this._httpClient);
    merge(this.paginator.page)
      .pipe(
        startWith({}),
        switchMap(() => {
          return this.listingDataSource!.retrieveServiceListing(
            this.paginator.pageIndex
          );
          // .pipe(catchError(() => Observable(null)));
        }),
        map((data) => {
          if (data === null) {
            return [];
          }

          return data;
        })
      )
      .subscribe((data) => {
        this.listings$ = data;
        // console.log(this.data);
        return this.listings$;
      });
  }

Here is the error

ERROR TypeError: Cannot read properties of undefined (reading 'page')
    at ListingsComponent.ngAfterViewInit (listings.component.ts:271)
    at callHook (core.js:3281)
    at callHooks (core.js:3251)
    at executeInitAndCheckHooks (core.js:3203)
    at refreshView (core.js:7438)
    at refreshEmbeddedViews (core.js:8468)
    at refreshView (core.js:7391)
    at refreshComponent (core.js:8514)
    at refreshChildComponents (core.js:7173)
    at refreshView (core.js:7417)

I have absolutely no idea what it is that I am doing wrong. I have done a similar implementation 3 months ago on another project and it seemed to work fine then

Solution

In case anyone has this problem. The issue was that the mat-paginator is declared inside the ng-container and the ng-container only exits when the asynchronous listings operation is complete <ng-container *ngIf="listings$ | async as listings">

This is what caused the error. The solution was to move the mat-paginator outside the ng-container

Answered By – Isidbigi

Answer Checked By – David Marino (AngularFixing Volunteer)

Leave a Reply

Your email address will not be published.