Provided 'undefined' where a stream was expected. Can provide an Observable, Promise, Array, or Iterable

4.3k Views Asked by At

I have been trying to implement server side pagination using mat-paginator & have faced a lot of difficulties. I've checked various blogs & tutorials but none of them helped me much to achieve my goal.

Service-

getAllCategoryByPage(data?: any): Observable<any> {
    var Url = `/Categories/GetAll`;
    return this.http
      .post<any>(Url, data)
      .pipe(catchError(this.handleError<any>('getAllCategoryByPage', [])));
  }

Components .ts-

@ViewChild(MatPaginator) paginator: MatPaginator;
@ViewChild(MatSort) sort: MatSort; //sorting is not mandatory in my case
ngOnInit(): void {
    this.loadCategoryList;
    this.dataSource.paginator = this.paginator;
  }
  ngAfterViewInit() {
    this.loadCategoryList();
     this.dataSource.paginator = this.paginator;
  }
loadCategoryList = (): void => {
    this.paginator.page.subscribe((resp) => {console.log(resp);});    
    merge(this.paginator.page)
      .pipe(
        startWith({}),
        switchMap(() => {
          this.asyncService.start();
          console.log(this.paginator.pageIndex ,this.paginator.pageSize);
          return this.categoryService.getAllCategoryByPage(
            {
              "page": this.paginator.pageIndex + 1,
              "pageSize": this.paginator.pageSize,
              "searchString": ""
            }
          )
        })
      )
      .subscribe(
        data => {
          console.log(data.apiData);
          this.length = data.totalRecord;
          this.dataSource.paginator = data.apiData;
          this.asyncService.finish();
        }
      );
  };

Html-

<table mat-table [dataSource]="dataSource">
      <ng-container matColumnDef="sl">
        <th mat-header-cell *matHeaderCellDef> SL. </th>
        <td mat-cell *matCellDef="let element; let i = index;"> {{i+1}} </td>
      </ng-container>
      <ng-container matColumnDef="name">
        <th mat-header-cell *matHeaderCellDef >CATEGORY NAME </th>
        <td mat-cell *matCellDef="let element"> {{element.categoryName}} </td>
      </ng-container>
      <ng-container matColumnDef="status">
        <th mat-header-cell *matHeaderCellDef >STATUS </th>
        <td mat-cell *matCellDef="let element">
         {{element.recStatus}}
        </td>
      </ng-container>
      <ng-container matColumnDef="actions">
        <th mat-header-cell *matHeaderCellDef>ACTIONS</th>
        <td mat-cell *matCellDef="let row" >
          <button class="table-button-action" style="color: red;" (click)="deleteRow(row)" >
            <mat-icon>clear</mat-icon>
          </button>
          <button class="table-button-action" style="color:royalblue;" (click)="onEdit(row)">
            <mat-icon>create</mat-icon>
          </button>
        </td>
      </ng-container>
      <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
      <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
    </table>
    <mat-paginator [length]= "length" [pageSizeOptions]="[5, 10, 25, 100]">
    </mat-paginator>

I am not getting the data in the table. Here, I'm getting error when the page is loaded as well as when I am navigating through the pages (using next & previous buttons) which I've no clue for what the error is occurring & how to solve it

Can anyone please guide me to fix it so it works perfectly?

Thanks in advance :)

3

There are 3 best solutions below

2
On

It seems that the service function getAllCategoryByPage, doesn't return a proper Observable, and I expect that happens because the catchError isn't properly (you passed the function directly within it, without returning an observable).

So could you please try the following:

getAllCategoryByPage(data?: any): Observable<any> {
    var Url = `/Categories/GetAll`;
    return this.http.post<any>(Url, data).pipe(
        catchError(() => {
            this.handleError<any>('getAllCategoryByPage', []);
            return EMPTY;
        })
    );
}
2
On

In your subscribe handler you have this:

this.dataSource.paginator = data.apiData;

You should assign the data to this.dataSource.data property instead. Try this:

this.dataSource.data = data.apiData;
0
On

I had exact same situation. The problem was in dependency injection when my module which provided CustomDatePickerIntl wrongly. The solution was to change: from: { provide: MatDatepickerIntl, useValue: CustomMatDatePickerIntl }

to: { provide: MatDatepickerIntl, useClass: CustomMatDatePickerIntl }

Check if there are no wrong object properties like useValue instead of proper useClass.