Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Table: Paginator/Sorting for dynamic data does not work (Bug) #8381

Closed
saitho opened this issue Nov 11, 2017 · 13 comments
Closed

Table: Paginator/Sorting for dynamic data does not work (Bug) #8381

saitho opened this issue Nov 11, 2017 · 13 comments

Comments

@saitho
Copy link

saitho commented Nov 11, 2017

Bug, feature request, or proposal:

Currently it is not possible to use the paginator with dynamic data that comes from Subjects (or initially Observables). The paginator seems to work with _data (initialData) set in the MatTableDataSource constructor. You can provide an Array that then transformed into a BehaviorSubject; however passing in a BehaviourSubject directly (e.g. from a service that provides the dynamic data) should be a thing - that would fix the issue described above.

What is the expected behavior?

The table should refresh when switching pages via the paginator.

What is the current behavior?

The table does not refresh when switching pages via the paginator.

What are the steps to reproduce?

Unfortunately I can't provide a functional Plunker because the data I'm using comes from my backend app... But you can find the relevant parts here: http://plnkr.co/edit/exXUHnTlOiEipaH97m4n

Basically you setup a regular MatTable and assign a DataSource. Then you return the BehaviourSubject in your DataSource's connect() method. This makes the data appear in the table - but you won't be able to sort or paginate.

What is the use-case or motivation for changing an existing behavior?

Pagination and sorting should also work with dynamic data. ;)

Which versions of Angular, Material, OS, TypeScript, browsers are affected?

Material 2

Is there anything else we should know?

It's my third week with Angular. ^^

@willshowell
Copy link
Contributor

I don't believe this change is necessary.

  1. When using a custom data source implementation, you can do whatever you want and pass any observable streams or static data you need into the data source.
  2. When using MatTableDataSource, you are not confined to the initial data and can use the data property to update it. Pagination and sorting will still work fine.
// create data source
this.myDataSource = new MatTableDataSource(initialData);

// update data in data source when available
this.streamOfDataUpdates.subscribe(newData => this.myDataSource.data = newData);

@saitho
Copy link
Author

saitho commented Nov 13, 2017

True, that works... I didn't think about that, even though I did a similar thing to fill my data list... ^^

@saitho saitho closed this as completed Nov 13, 2017
@umutesen
Copy link

How would you subscribe to an array of objects to detect changes? binding mat table to an array and using push to add a new item does not update table data source. So I am newing up the data source object:

selectedProcedures is a mat data source object.

const data= this.selectedProcedures.data;
data.push(result);

// force change detection of mat-table by newing up the data source
this.selectedProcedures.data = data;

@mucbits
Copy link

mucbits commented Apr 26, 2018

The data object would still have the same reference. Try this:

// force change detection of mat-table by newing up the data source
this.selectedProcedures.data = [...this.selectedProcedures.data, result];

@vikaskumar81
Copy link

I tried both above ways even datasource is data is changed, but still we don't find mat-table working and adding the new row

@bigyanshr
Copy link

bigyanshr commented Aug 28, 2018

It might help if you do the following after loading the data.

this.paginator.page // your paginator instance
      .pipe(
        tap(() => data) // your dynamic data
      );

@ghost
Copy link

ghost commented Oct 11, 2018

The data object would still have the same reference. Try this:

// force change detection of mat-table by newing up the data source
this.selectedProcedures.data = [...this.selectedProcedures.data, result];

is this work if I go to the next page and further come to the previous page? I don't think it will work.

@leajaymakwana
Copy link

I don't believe this change is necessary.

  1. When using a custom data source implementation, you can do whatever you want and pass any observable streams or static data you need into the data source.
  2. When using MatTableDataSource, you are not confined to the initial data and can use the data property to update it. Pagination and sorting will still work fine.
// create data source
this.myDataSource = new MatTableDataSource(initialData);

// update data in data source when available
this.streamOfDataUpdates.subscribe(newData => this.myDataSource.data = newData);

@leajaymakwana
Copy link

leajaymakwana commented Apr 28, 2019

This works for me like magic. Thanks

@bhumin3i
Copy link

bhumin3i commented May 17, 2019

@willshowell i'm stuck with use pagination with BehaviorSubject

i was used BehaviorSubject for update table value.

Init var:
zoneCategoryItems: BehaviorSubject<IZoneCategoryInterface[]> = new BehaviorSubject([]);
**Service call for getting data from server ** :

this._masterService.getMasterZoneCategoryData().subscribe((Category: IZoneCategoryInterface[]) => {
           this.zoneCategoryItems.next(Category);
    }, () => {
      this.zoneCategoryItems.next(null);
    })

if you want to update just used

this.zoneCategoryItems.next([...this.zoneCategoryItems.getValue(), result]);

But i face one ISSUE i can't use MatPaginator with BehaviorSubject anyone some idea?
if i want to use MatPagination it must be zoneCategoryItems =new MatTableDataSource<IZoneCategoryInterface>(); ?

@ricardosaracino
Copy link

ricardosaracino commented Jun 21, 2019

Not to bad with a bit of massaging

export class TopicTableDataSource extends DataSource<TopicTableItem> {
  private sort: MatSort;
  private dataSubject = new BehaviorSubject<TopicTableItem[]>([]);

  constructor(private readonly topicsService: TopicsService) {
    super();
    this.topicsService.findAllTopics().pipe(
      catchError(() => of([])),
    ).subscribe(data => this.dataSubject.next(data));
  }

  public setSort(sort: MatSort) {
    this.sort = sort;
    this.sort.sortChange.subscribe(() => this.dataSubject.next(this.getSortedData(this.dataSubject.getValue())))
  }
  connect(): Observable<TopicTableItem[]> {
    return this.dataSubject.asObservable();
  }

  constructor(private readonly topicsService: TopicsService) {
  }

  ngOnInit() {
    this.dataSource = new TopicTableDataSource(this.topicsService);
  }

  ngAfterViewInit() {
    this.dataSource.setSort(this.sort);
    this.table.dataSource = this.dataSource;
  }
}

@bhumin3i
Copy link

@ricardosaracino Thanks so much :)

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 11, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants