Angular 7 Sorting on Custom DataSource












1















I've got a custom DataSource that I've created in my Risk component to reach out to an API, retrieve a list of Risks and display them in a table. The table displays properly however my Sorting isn't working.



I'm not entirely sure why however I call a refresh on the page every time the sort-able header is clicked, yet nothing. I've tried several different examples & configurations and I'm missing something.



Here's my risk.component.ts



export class RiskDashboardComponent implements AfterViewInit, OnInit {

@ViewChild(MatSort) sort: MatSort;

dataSource: RiskDataSource;

displayedColumns = ['riskName'];

constructor(private riskService: RiskManagmentService) {}

ngOnInit() {
this.dataSource = new RiskDataSource(this.riskService);
this.dataSource.loadRisks();
}

ngAfterViewInit() {
merge(this.sort.sortChange).pipe(
tap(() => this.loadRisksPage())
)
.subscribe();
}

loadRisksPage() {
this.dataSource.loadRisks();
}


}

export class RiskDataSource implements DataSource<IRisk> {

private risksSubject = new BehaviorSubject<IRisk>();
private loadingSubject = new BehaviorSubject<boolean>(false);

constructor(private riskService: RiskManagmentService) {}

connect(collectionViewer: CollectionViewer): Observable<IRisk> {
return this.risksSubject.asObservable();

}

disconnect(collectionViewer: CollectionViewer): void {
this.risksSubject.complete();
this.loadingSubject.complete();
}

loadRisks() {
this.loadingSubject.next(true);
this.riskService.getAllRisks().subscribe(risk => this.risksSubject.next(risk));
}
}


The risk.component.html



<div>
<mat-table class="lessons-table mat-elevation-z8" [dataSource]="dataSource"
matSort matSortActive="riskName">
<ng-container matColumnDef="riskName">
<mat-header-cell *matHeaderCellDef mat-sort-header> Risk Name </mat-header-cell>
<mat-cell *matCellDef="let risk"> {{risk.riskRegister.riskName}} </mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
</mat-table>
</div>


(inb4 missing div tag, its in there, just isn't showing)



Every time the Risk Name order arrow is clicked it queries the database again for the list of risks



Any help would be greatly appreciated!










share|improve this question





























    1















    I've got a custom DataSource that I've created in my Risk component to reach out to an API, retrieve a list of Risks and display them in a table. The table displays properly however my Sorting isn't working.



    I'm not entirely sure why however I call a refresh on the page every time the sort-able header is clicked, yet nothing. I've tried several different examples & configurations and I'm missing something.



    Here's my risk.component.ts



    export class RiskDashboardComponent implements AfterViewInit, OnInit {

    @ViewChild(MatSort) sort: MatSort;

    dataSource: RiskDataSource;

    displayedColumns = ['riskName'];

    constructor(private riskService: RiskManagmentService) {}

    ngOnInit() {
    this.dataSource = new RiskDataSource(this.riskService);
    this.dataSource.loadRisks();
    }

    ngAfterViewInit() {
    merge(this.sort.sortChange).pipe(
    tap(() => this.loadRisksPage())
    )
    .subscribe();
    }

    loadRisksPage() {
    this.dataSource.loadRisks();
    }


    }

    export class RiskDataSource implements DataSource<IRisk> {

    private risksSubject = new BehaviorSubject<IRisk>();
    private loadingSubject = new BehaviorSubject<boolean>(false);

    constructor(private riskService: RiskManagmentService) {}

    connect(collectionViewer: CollectionViewer): Observable<IRisk> {
    return this.risksSubject.asObservable();

    }

    disconnect(collectionViewer: CollectionViewer): void {
    this.risksSubject.complete();
    this.loadingSubject.complete();
    }

    loadRisks() {
    this.loadingSubject.next(true);
    this.riskService.getAllRisks().subscribe(risk => this.risksSubject.next(risk));
    }
    }


    The risk.component.html



    <div>
    <mat-table class="lessons-table mat-elevation-z8" [dataSource]="dataSource"
    matSort matSortActive="riskName">
    <ng-container matColumnDef="riskName">
    <mat-header-cell *matHeaderCellDef mat-sort-header> Risk Name </mat-header-cell>
    <mat-cell *matCellDef="let risk"> {{risk.riskRegister.riskName}} </mat-cell>
    </ng-container>
    <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
    <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
    </mat-table>
    </div>


    (inb4 missing div tag, its in there, just isn't showing)



    Every time the Risk Name order arrow is clicked it queries the database again for the list of risks



    Any help would be greatly appreciated!










    share|improve this question



























      1












      1








      1








      I've got a custom DataSource that I've created in my Risk component to reach out to an API, retrieve a list of Risks and display them in a table. The table displays properly however my Sorting isn't working.



      I'm not entirely sure why however I call a refresh on the page every time the sort-able header is clicked, yet nothing. I've tried several different examples & configurations and I'm missing something.



      Here's my risk.component.ts



      export class RiskDashboardComponent implements AfterViewInit, OnInit {

      @ViewChild(MatSort) sort: MatSort;

      dataSource: RiskDataSource;

      displayedColumns = ['riskName'];

      constructor(private riskService: RiskManagmentService) {}

      ngOnInit() {
      this.dataSource = new RiskDataSource(this.riskService);
      this.dataSource.loadRisks();
      }

      ngAfterViewInit() {
      merge(this.sort.sortChange).pipe(
      tap(() => this.loadRisksPage())
      )
      .subscribe();
      }

      loadRisksPage() {
      this.dataSource.loadRisks();
      }


      }

      export class RiskDataSource implements DataSource<IRisk> {

      private risksSubject = new BehaviorSubject<IRisk>();
      private loadingSubject = new BehaviorSubject<boolean>(false);

      constructor(private riskService: RiskManagmentService) {}

      connect(collectionViewer: CollectionViewer): Observable<IRisk> {
      return this.risksSubject.asObservable();

      }

      disconnect(collectionViewer: CollectionViewer): void {
      this.risksSubject.complete();
      this.loadingSubject.complete();
      }

      loadRisks() {
      this.loadingSubject.next(true);
      this.riskService.getAllRisks().subscribe(risk => this.risksSubject.next(risk));
      }
      }


      The risk.component.html



      <div>
      <mat-table class="lessons-table mat-elevation-z8" [dataSource]="dataSource"
      matSort matSortActive="riskName">
      <ng-container matColumnDef="riskName">
      <mat-header-cell *matHeaderCellDef mat-sort-header> Risk Name </mat-header-cell>
      <mat-cell *matCellDef="let risk"> {{risk.riskRegister.riskName}} </mat-cell>
      </ng-container>
      <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
      <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
      </mat-table>
      </div>


      (inb4 missing div tag, its in there, just isn't showing)



      Every time the Risk Name order arrow is clicked it queries the database again for the list of risks



      Any help would be greatly appreciated!










      share|improve this question
















      I've got a custom DataSource that I've created in my Risk component to reach out to an API, retrieve a list of Risks and display them in a table. The table displays properly however my Sorting isn't working.



      I'm not entirely sure why however I call a refresh on the page every time the sort-able header is clicked, yet nothing. I've tried several different examples & configurations and I'm missing something.



      Here's my risk.component.ts



      export class RiskDashboardComponent implements AfterViewInit, OnInit {

      @ViewChild(MatSort) sort: MatSort;

      dataSource: RiskDataSource;

      displayedColumns = ['riskName'];

      constructor(private riskService: RiskManagmentService) {}

      ngOnInit() {
      this.dataSource = new RiskDataSource(this.riskService);
      this.dataSource.loadRisks();
      }

      ngAfterViewInit() {
      merge(this.sort.sortChange).pipe(
      tap(() => this.loadRisksPage())
      )
      .subscribe();
      }

      loadRisksPage() {
      this.dataSource.loadRisks();
      }


      }

      export class RiskDataSource implements DataSource<IRisk> {

      private risksSubject = new BehaviorSubject<IRisk>();
      private loadingSubject = new BehaviorSubject<boolean>(false);

      constructor(private riskService: RiskManagmentService) {}

      connect(collectionViewer: CollectionViewer): Observable<IRisk> {
      return this.risksSubject.asObservable();

      }

      disconnect(collectionViewer: CollectionViewer): void {
      this.risksSubject.complete();
      this.loadingSubject.complete();
      }

      loadRisks() {
      this.loadingSubject.next(true);
      this.riskService.getAllRisks().subscribe(risk => this.risksSubject.next(risk));
      }
      }


      The risk.component.html



      <div>
      <mat-table class="lessons-table mat-elevation-z8" [dataSource]="dataSource"
      matSort matSortActive="riskName">
      <ng-container matColumnDef="riskName">
      <mat-header-cell *matHeaderCellDef mat-sort-header> Risk Name </mat-header-cell>
      <mat-cell *matCellDef="let risk"> {{risk.riskRegister.riskName}} </mat-cell>
      </ng-container>
      <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
      <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
      </mat-table>
      </div>


      (inb4 missing div tag, its in there, just isn't showing)



      Every time the Risk Name order arrow is clicked it queries the database again for the list of risks



      Any help would be greatly appreciated!







      angular angularjs-directive angular-material2






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Jan 8 at 21:39









      marc_s

      581k13011221268




      581k13011221268










      asked Jan 2 at 3:01









      Matt BrownMatt Brown

      62




      62
























          1 Answer
          1






          active

          oldest

          votes


















          0














          As you are using your own datasource most of the example in the angular material documentation website does not apply to you.



          Firstly, you need to get the matsort from the view child and pass it into the datasource.



          RiskDashBoardComponent



          Add this



          ViewChild(MatSort) sort: MatSort;
          ngOnInit() {
          this.dataSource = new RiskDataSource(this.riskService, this.sort);
          this.dataSource.loadRisks();
          }


          You will require a little knowledge of observables here.



          Now you need to return an observable that listen to two things by merging them. So when either the risksSubject gets a new data or mat sort is emitting new sort sequence you will handle the data always by getting the current value of the sort direction and the current value of the risksSubject.



          You can see how to implement a custom sortData function from the angular material documentation site.



          https://material.angular.io/components/sort/examples



          RiskDataSource



          connect(collectionViewer: CollectionViewer): Observable<IRisk> {
          const displayDataChanges = [
          this.risksSubject,
          this._sort.sortChange
          ];
          merge(...displayDataChanges).pipe(map(() => {
          return this.sortData(this.risksSubject.getValue());
          }));

          }

          loadRisks() {
          this.loadingSubject.next(true);
          this.riskService.getAllRisks().subscribe(risk =>
          this.risksSubject.next(risk));
          }


          **






          share|improve this answer























            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54000759%2fangular-7-sorting-on-custom-datasource%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            0














            As you are using your own datasource most of the example in the angular material documentation website does not apply to you.



            Firstly, you need to get the matsort from the view child and pass it into the datasource.



            RiskDashBoardComponent



            Add this



            ViewChild(MatSort) sort: MatSort;
            ngOnInit() {
            this.dataSource = new RiskDataSource(this.riskService, this.sort);
            this.dataSource.loadRisks();
            }


            You will require a little knowledge of observables here.



            Now you need to return an observable that listen to two things by merging them. So when either the risksSubject gets a new data or mat sort is emitting new sort sequence you will handle the data always by getting the current value of the sort direction and the current value of the risksSubject.



            You can see how to implement a custom sortData function from the angular material documentation site.



            https://material.angular.io/components/sort/examples



            RiskDataSource



            connect(collectionViewer: CollectionViewer): Observable<IRisk> {
            const displayDataChanges = [
            this.risksSubject,
            this._sort.sortChange
            ];
            merge(...displayDataChanges).pipe(map(() => {
            return this.sortData(this.risksSubject.getValue());
            }));

            }

            loadRisks() {
            this.loadingSubject.next(true);
            this.riskService.getAllRisks().subscribe(risk =>
            this.risksSubject.next(risk));
            }


            **






            share|improve this answer




























              0














              As you are using your own datasource most of the example in the angular material documentation website does not apply to you.



              Firstly, you need to get the matsort from the view child and pass it into the datasource.



              RiskDashBoardComponent



              Add this



              ViewChild(MatSort) sort: MatSort;
              ngOnInit() {
              this.dataSource = new RiskDataSource(this.riskService, this.sort);
              this.dataSource.loadRisks();
              }


              You will require a little knowledge of observables here.



              Now you need to return an observable that listen to two things by merging them. So when either the risksSubject gets a new data or mat sort is emitting new sort sequence you will handle the data always by getting the current value of the sort direction and the current value of the risksSubject.



              You can see how to implement a custom sortData function from the angular material documentation site.



              https://material.angular.io/components/sort/examples



              RiskDataSource



              connect(collectionViewer: CollectionViewer): Observable<IRisk> {
              const displayDataChanges = [
              this.risksSubject,
              this._sort.sortChange
              ];
              merge(...displayDataChanges).pipe(map(() => {
              return this.sortData(this.risksSubject.getValue());
              }));

              }

              loadRisks() {
              this.loadingSubject.next(true);
              this.riskService.getAllRisks().subscribe(risk =>
              this.risksSubject.next(risk));
              }


              **






              share|improve this answer


























                0












                0








                0







                As you are using your own datasource most of the example in the angular material documentation website does not apply to you.



                Firstly, you need to get the matsort from the view child and pass it into the datasource.



                RiskDashBoardComponent



                Add this



                ViewChild(MatSort) sort: MatSort;
                ngOnInit() {
                this.dataSource = new RiskDataSource(this.riskService, this.sort);
                this.dataSource.loadRisks();
                }


                You will require a little knowledge of observables here.



                Now you need to return an observable that listen to two things by merging them. So when either the risksSubject gets a new data or mat sort is emitting new sort sequence you will handle the data always by getting the current value of the sort direction and the current value of the risksSubject.



                You can see how to implement a custom sortData function from the angular material documentation site.



                https://material.angular.io/components/sort/examples



                RiskDataSource



                connect(collectionViewer: CollectionViewer): Observable<IRisk> {
                const displayDataChanges = [
                this.risksSubject,
                this._sort.sortChange
                ];
                merge(...displayDataChanges).pipe(map(() => {
                return this.sortData(this.risksSubject.getValue());
                }));

                }

                loadRisks() {
                this.loadingSubject.next(true);
                this.riskService.getAllRisks().subscribe(risk =>
                this.risksSubject.next(risk));
                }


                **






                share|improve this answer













                As you are using your own datasource most of the example in the angular material documentation website does not apply to you.



                Firstly, you need to get the matsort from the view child and pass it into the datasource.



                RiskDashBoardComponent



                Add this



                ViewChild(MatSort) sort: MatSort;
                ngOnInit() {
                this.dataSource = new RiskDataSource(this.riskService, this.sort);
                this.dataSource.loadRisks();
                }


                You will require a little knowledge of observables here.



                Now you need to return an observable that listen to two things by merging them. So when either the risksSubject gets a new data or mat sort is emitting new sort sequence you will handle the data always by getting the current value of the sort direction and the current value of the risksSubject.



                You can see how to implement a custom sortData function from the angular material documentation site.



                https://material.angular.io/components/sort/examples



                RiskDataSource



                connect(collectionViewer: CollectionViewer): Observable<IRisk> {
                const displayDataChanges = [
                this.risksSubject,
                this._sort.sortChange
                ];
                merge(...displayDataChanges).pipe(map(() => {
                return this.sortData(this.risksSubject.getValue());
                }));

                }

                loadRisks() {
                this.loadingSubject.next(true);
                this.riskService.getAllRisks().subscribe(risk =>
                this.risksSubject.next(risk));
                }


                **







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Jan 2 at 8:29









                Ho Wei LipHo Wei Lip

                305210




                305210
































                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54000759%2fangular-7-sorting-on-custom-datasource%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    'app-layout' is not a known element: how to share Component with different Modules

                    android studio warns about leanback feature tag usage required on manifest while using Unity exported app?

                    WPF add header to Image with URL pettitions [duplicate]