Angular 6 Material table data connection

I'm encountering difficulty setting the datasource for the Angular Material table.

Here is what I am trying to accomplish:

export class ServersTableDataSource extends DataSource<Server> {
  data: Server[] = EXAMPLE_DATA;

  constructor(private paginator: MatPaginator, private sort: MatSort, private serversService: ServersService) {
    super();
    this.data = this.serversService.getServers();
  }
  connect(): Observable<Server[]> {
    const dataMutations = [
      observableOf(this.data),
      this.paginator.page,
      this.sort.sortChange
    ];

    // Set the paginators length
    this.paginator.length = this.data.length;

    return merge(...dataMutations).pipe(map(() => {
      return this.getPagedData(this.getSortedData([...this.data]));
    }));
  }


export class ServersTableComponent implements OnInit {

  constructor(private serversService: ServersService) { }

  ngOnInit() {
    this.dataSource = new ServersTableDataSource(this.paginator, this.sort, this.serversService);
    this.serversService.serversChanges.subscribe(() => {
      this.dataSource.data = this.serversService.getServers();
    });
    //done this way because for unknown reason if i return an observable,
    //it doesn't pass a value. Anyway, this isn't relevant. The point is that this.dataSource.data  is set.
  }

In this scenario, although there is observableOf(this.data) in the connect method, changes to this.dataSource.data do not take effect.

The only solution I found was to reinitialize the datasource each time, which seems inefficient considering the table is frequently updated with websocket data.

  ngOnInit() {
    this.dataSource = new ServersTableDataSource(this.paginator, this.sort, this.serversService);
    this.serversService.serversChanges.subscribe(() => {
      this.dataSource = new ServersTableDataSource(this.paginator, this.sort, this.serversService);
    });
  }

Answer №1

The solution involved implementing a new updating mechanism using BehaviorSubject and keeping track of the rows by their index (as tracking by unique object sub-properties was not functioning properly for some reason).

Data Source:

export class ServersTableDataSource extends DataSource<Server> {
  data: Server[] = [];

  constructor(private paginator: MatPaginator, private sort: MatSort, private serversService: ServersService) {
    super();
  }


  connect(): Observable<Server[]> {
    return new Observable<Server[]>(observer => {
      this.serversService.getServersSubj().subscribe((servers) => {
        if (servers) {
          return this.applyMutations(servers).subscribe(data => {
            observer.next(data);
          });
        }
      });
    });
  }

  disconnect() {

  }

  applyMutations(tmpData: Server[]): Observable<Server[]> {
    const dataMutations = [
      observableOf(tmpData),
      this.paginator.page,
      this.sort.sortChange
    ];

    // Set the paginators length
    this.paginator.length = this.data.length;

    return merge(...dataMutations).pipe(map(() => {
      return this.getPagedData(this.getSortedData([...tmpData]));
    }));
  }

Tracking Changes:

  <mat-table #table [dataSource]="dataSource"
         [trackBy]="trackByIndex"
         multiTemplateDataRows
         matSort
         aria-label="Elements">

  ***in component:***

  trackByIndex(index, item) {
    return index;
  }

this.serversService.getServersSubj()
now utilizes a BehaviorSubject.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

JavaScript Stub Pusher (Event)

I rely on pusher for handling my sockets and events. The pusher channels I use are encapsulated within an object that is passed as a key/value pair to the child component. The actual channel is accessed through this.channel.value, while this.channel.key s ...

A step-by-step guide on simulating firestore interactions using mocha

Within my codebase, I have a straightforward wrapper function that retrieves a specific document from firestore in the following manner: export const fetchSettings = async (firestore):Promise<MyDocment>=>{ try { const response = await ...

JS : Removing duplicate elements from an array and replacing them with updated values

I have an array that looks like this: let arr = ['11','44','66','88','77','00','66','11','66'] Within this array, there are duplicate elements: '11' at po ...

My instance transforms with the arrival of a JSON file

I'm grappling with a query about data types in TypeScript and Angular 2. I defined a class in TypeScript export class product{ public id:number; public name:string; public status:boolean; constructor(){} } and I initialize an instanc ...

Using Typescript/JSX to assign a class instance by reference

Looking to access an object's property by reference? See the code snippet below; class Point{ x:number; y:number; constructor(x,y) { this.x=x; this.y=y; } } const a = { first: new Point(8,9), second: new Point(10,12) }; let someBoo ...

Capturing the file path reference from subsribe and saving it in Firebase

Currently, I have a script that is responsible for uploading my image once the form is submitted. updateUser(user: User, privateUser: PrivateUser, dob) { //store img in storage if(this.file){ var path = `users/${this.userID}/${this.file.name}` var ...

Using Angular 7 with FileSaver.js

I am currently facing a situation where I need to download data in the form of an Excel file. My setup involves Angular 7 for the UI and a Java Spring REST API service. The REST API is responsible for generating the Excel file and sending it back to Angula ...

The ability to choose only one option in a checkbox within a grid view column

In my grid view, I have a checkbox in the last column. I am trying to ensure that only one row can be selected at a time. <tr *ngFor="let permit of PermitDetails" (click)="GoByClick(permit)"> <td style="text-align: center">{{permit.TVA_BAT ...

Ways to exclude sourcemaps in Angular-CLI version 6 and above

Is there a way to build using ng build in Angular-CLI 6+ without including sourcemaps? In the past, I would use the --no-sourcemap or --sourcemap=false parameter, but it seems that they are no longer working as I now receive an error message saying: Un ...

Setting up the TypeScript compiler locally in the package.json file

UPDATE #1: It appears that I have managed to come up with a functional configuration, but I am open to any suggestions for improvement. Feel free to check out the answer here: THE ORIGINAL INQUIRY: I am in the process of setting up my environment so that ...

What could be the reason for getting the message "Unsanitized data from an HTTP parameter is being sent" while utilizing the usual Node Oracledb configuration for a GET request?

In my current setup, we are utilizing an Angular frontend along with a Node backend. The specific line causing issues can be found in the Controller code below. res.send(rows); Given that our database is Oracle, we are making use of the npm package: htt ...

Identifying the scenario where Partial<T> inherits from T

I am facing a scenario where I am working towards achieving a specific "state": type State = { foo: number, bar: number, baz?: string }; Initially, I may not have reached the complete State yet but rather align with the structure of Partial<State>. ...

Passing a variable from a child component to a parent component in Angular 2 using EventEmitter and a

I am experiencing a challenge with the Event Emitter in my child component. My goal is to pass a variable with EventEmitter to the parent component, but I would like to include a timeout function. Currently, the code looks like this: CHILD: export class ...

What is the reason for the successful compilation of "require" and the failure of "import"?

Currently getting familiar with TypeScript/JavaScript, as well as Node.js, I am in the process of creating a basic script to run via command line. After adding the dependency archiver and inserting import archiver from 'archiver';to my script, I ...

Insert a fresh element above the existing elements fetched from the API

My application consists of two components: add-product.component and show-list.component. The show-list component displays a list obtained from the list-product API, which requires 3 parameters in the body (user_id, session_key, page). The third parameter ...

Ways to inform TypeScript of the potential return type when a generic's parameter can be either a string or a number

Let's take a look at a function with the following signature: function removeNumbersOrStringsElementsFromArray( targetArray: Array<number | string>, targetElementOrMultipleOfThem: number | string | Array<number | string> ): { upd ...

Leverage the power of an Angular component for repeated

Attempting to recycle an Angular component within the given tree structure. https://i.sstatic.net/LVvwO.png The desired component, existing-savings, is located in transfer-guide. Trying to utilize this component in retirement-contributions-information. ...

UI thread was blocked due to withProgress being invoked from an external library function

Currently enhancing an extension that is almost finished, but facing a challenge in adding visual cues for lengthy operations. Initially suspected a missing async/await in the code, but struggling to identify the cause. The progress indicator isn't di ...

Constantly receiving an undefined value when trying to access a variable in an ngrx Observable

Here is the code snippet I am working with: language.component.ts form: FormGroup; first: AbstractControl; second: AbstractControl; constructor(private _fb: FormBuilder) { this.first = new FormControl('', [Validators.required, Va ...

Revise the observable to trigger a NgbModal from a service

I have a situation in my Angular 11 service where I am using a Ngbmodal component to subscribe when it is closed. Below is the code snippet: showMessage(messageData: MessageDataDTO): Observable<MessageResult> { return new Observable((result) =&g ...