0

Let me preface this question by stating that I am fairly new to Angular and this is my first experience with material table. I have a material table that resides in one component. I have a data fetching routine that resides in another component. Based on some selection made in this second component I need to update the data in the material table. I am not sure how I can go about doing this, and all my experimenting has failed. I have tried looking for questions on this forum that address a similar scenario and have not been successful so far.

I have tried to bind the material table's typescript file variable directly and via an emitter but the only time I see data is on ngInit of the second form (the one that computes the data). Thereafter, when the data is updated (see performButtonClickAction() below) I see that the data is correctly populated in the emitter but does not show up in the table. I guess that I need to know how to trigger an update / refresh event in the material table component.

Component that fetches data:

<div>    
    <div >
        <div >
                <div > 
                    <button (click)="performButtonClickAction('ManualReview')">  </button>
                </div>
                <div >
                    <button (click)="performButtonClickAction('PendingCustomer')"></button>
                </div>
                <div >
                    <button (click)="performButtonClickAction('DecisionRendered')"></button>
                </div>
                <div >
                    <button (click)="performButtonClickAction('RefreshComplete')"></button>
                </div>
                <div >
                    <button (click)="performButtonClickAction('AllMyDeals')"> </button>
                </div>
        </div>

        <div >
            <op-credit-view-body-table [data]="refreshDetails" ></op-credit-view-body-table>
        </div>
    </div>
</div>

In the html above op-credit-view-body-table [data]="refreshDetails" is a reference to the material table component.


Typescript file methods that fetches data when some selection is made:

@Output() updatedRecords = new EventEmitter<RefreshDetailRecords[]>();

performButtonClickAction(value: string) {
      this.currentRefreshSelected = RefreshType[value];

      if (this.currentRefreshSelected == 4)
        this.refreshDetails =  this.fundationService.getRefreshedRecords();
      else
        this.refreshDetails =  this.refreshDetails.filter(x => x.currentStatusId == this.currentRefreshSelected);

      this.updatedRecords.emit(this.refreshDetails);
  }

Material table typescript file:

@Input() data: RefreshDetailRecords[]; <-- This is set in the html snippet shown above

ngOnInit() {

    this.dataSource = new CreditViewBodyTableDataSource();
    this.dataSource.data = this.data;
  }

The result that I am looking for is as that when the second form executes the performButtonClickAction() action, and the refreshDetailRecords[] object is updated, I need to somehow pass that message back to the material table component and have it update the table.

The current route is as follows:

The data fetching component's ts file initializes the data object refreshDetailRecords[] in the ngInit() method.

The data fetching form initialize the material tables "data" object in its own html as follows:

Material Datasource data resides in material component's ts file

Edric
  • 24,639
  • 13
  • 81
  • 91

2 Answers2

0

make a "getter" in the @Input, see the docs

@Input()
  set data(value:any[]) {
    this._data=value; //really if not use "data" you can remove this line
    this.dataSource = new CreditViewBodyTableDataSource();
    this.dataSource.data = value;
  }

  //really if not use "data" you can remove this line
  get data(): any[]{ return this._data; } 
}
Eliseo
  • 50,109
  • 4
  • 29
  • 67
  • Eliseo, so the getter/setter works fine to set the initial data, but the refreshes still do not show up in the grid. In debug I can see the refresh data triggering the getter() method and I can see the datasource being updated, but the UI does not reflect those changes. Is there somethign else that I need to do? Thanks. – MumbaiMann Sep 13 '19 at 18:57
  • MumbaiMann, you has a clasic parent-child comunicate with a simple input, must be work (check if pass thought the input using `console.log(value)`. if there a problem, try using a reference variable in the table and use table.renderRows(), but I think that must be innecesary https://stackoverflow.com/questions/47581267/how-to-add-data-dynamically-to-mat-table-datasource/52468899. – Eliseo Sep 13 '19 at 19:17
  • Eliseo, I have a console.log() in the getter, and I also set a break point where I update the datasource (this._data=value). I can verify that the updated data is making it all the way to the getter, i.e. to the material table component. I just do not see the table grid refreshign itself when the data changes – MumbaiMann Sep 13 '19 at 19:51
  • Eliseo, thanks again for your help. I got it all working. – MumbaiMann Sep 15 '19 at 14:58
0

use This:-

@Input()
  set data(value:any[]) {
    this.dataSource = value;
    const d = JSON.stingify(this.dataSource);
    this.dataSource = JSON.parse(d);
  }
Aarji George
  • 599
  • 4
  • 8
  • Thank you Aarji. Eliseo (above) suggested somethngn similar and I finally got it all working by tweaking the refresh portion. – MumbaiMann Sep 15 '19 at 14:58