Michael
Michael

Reputation: 297

Angular 7: Dynamically add rows to Material data table

How do I add data which I get from a service into my data table dynamically?

I get data from a dialog with the service AuthenticationService. My first thought was to use this.dataSource.push(this.transaction);, which doesn't work.

This is how I tried to do it:

export class TransactionPoolComponent implements OnInit {
  displayedColumns = ['sender', 'recipient', 'amount', 'fee'];
  dataSource = ELEMENT_DATA;
  transaction: Transaction;


  constructor(private _AS: AuthenticationService) {
  }

  ngOnInit() {
    this._AS.transaction$.subscribe( transaction => {
      this.transaction = transaction;
      this.dataSource.push(this.transaction);
      console.log(this.transaction);
      }
    );
  }
}

export interface Transaction {
  sender: number;
  recipient: string;
  amount: number;
  fee: string;
}

const ELEMENT_DATA: Transaction[] = [
];

Upvotes: 1

Views: 3193

Answers (3)

Pratham Sharma
Pratham Sharma

Reputation: 1

You just need to change the reference of the dataSource and it would detect changes automatically. Something like:

export class TransactionPoolComponent implements OnInit {
  displayedColumns = ['sender', 'recipient', 'amount', 'fee'];
  dataSource = ELEMENT_DATA;
  transaction: Transaction;


  constructor(private _AS: AuthenticationService) {
  }

  ngOnInit() {
    this._AS.transaction$.subscribe( transaction => {
      this.transaction = transaction;
      // You were pushing to dataSource but your data is stored in 'data' 
      // object of dataSource, and you need to changed the reference of the 
      // dataSource by assigning dataSource to itself or assigning a new Array 
      // to dataSource and it would automatically detect the changes and 
      // update the table
      this.dataSource.data = this.dataSource.data.push(this.transaction);
      console.log(this.transaction);
      }
    );
  }
}

export interface Transaction {
  sender: number;
  recipient: string;
  amount: number;
  fee: string;
}

const ELEMENT_DATA: Transaction[] = [
];

Upvotes: 0

Sajeetharan
Sajeetharan

Reputation: 222572

This should work if you see the data is getting added. You need to manually call the detectChanges to keep the ui updated. you can do the same with detectChanges()

you need to inject inside the constructor as,

constructor(private ref: ChangeDetectorRef) {

once you assign the data just call,

this.dataSource.push(this.transaction);
this.ref.detectChanges(); 

also one more mistake, you need to push the element to the array and then convery to dataTable,

this.ELEMENT_DATA.push(this.transaction);
this.dataSource = new DataSource(this.ELEMENT_DATA));

Upvotes: 2

phonex
phonex

Reputation: 51

you must change the datasource reference.

this.dataSource = new DataSource(new Array(old + new pushed value))

Edit:

Because you don't use **DataSource**, you can do the following
temp = this.datasource.slice();
temp.push(value);
this.datasource = temp;

Upvotes: 2

Related Questions