0
votes

Here is the component.ts

export class RoleListComponent {
    displayedColumns = ['roleAvatar', 'roleName']; // list of columns to show on UI
    dataSource: RoleDataSource;

    @ViewChild(MdSort) sort: MdSort;

    constructor(private roleService: RoleService, private router: Router) { }

    ngOnInit() {
        this.dataSource = new RoleDataSource(this.roleService, this.sort);
    }
}

export class RoleDataSource extends DataSource<any> {
    roles: Observable<Role[]>;
    constructor(private roleService: RoleService, private _sort: MdSort) {
        super();
    }
    /** Connect function called by the table to retrieve one stream containing the data to render. */
    connect(): Observable<Role[]> {

        this.roles = this.roleService.getRoles();
        const displayDataChanges = [
            this.roles,
            this._sort.mdSortChange,
        ];
        return Observable.merge(...displayDataChanges).map(() => {
            return this.getSortedData();
      });

    }
    disconnect() { }

    compare(a: string, b: string, isAsc: boolean) {
        return (a < b ? -1 : 1) * (isAsc ? 1 : -1);
    }
    /** Returns a sorted copy of the database data. */
    getSortedData(): Role[] {
        let sortedData:Role[];
        this.roles.subscribe(data => {
            debugger
            if (!this._sort.active || this._sort.direction == '') { return data; }

            sortedData = data.sort((a, b) => {
                let isAsc = this._sort.direction == 'asc';
                switch (this._sort.active) {
                    case 'roleAvatar': return this.compare(a.name[0], b.name[0], isAsc);
                    case 'roleName': return this.compare(a.name, b.name, isAsc);
                }
            });
            console.log(sortedData)
            return sortedData;
        });
        return sortedData;
    }
}

There is a roleService.getRoles() method of roleService that return the Observable of type Role[]. I have merged the observable of mdSort and the this.roles observable and returned the getSortedData().

Now in the getSortedData() method, I have subscribed the this.roles observable to get the array of roles and sorted that array and returned from inside the subscribe. There is the return of getSortedData() itself and on call of this method it returns method's return statement rather than subscribe's return, so sorted data is undefined and no records on UI. I am confused how can I solve this?

1

1 Answers

0
votes

Try returning an Observable<Role[]> from getSortedData() and using switchMap in connect().

export class RoleDataSource extends DataSource<any> {

  roles: Observable<Role[]>;

  constructor(private roleService: RoleService, private _sort: MdSort) {
      super();
  }

  /** Connect function called by the table to retrieve one stream containing the data to render. */
  connect(): Observable<Role[]> {

      this.roles = this.roleService.getRoles();

      const displayDataChanges = [
          this.roles,
          this._sort.mdSortChange,
      ];

      return Observable.merge(...displayDataChanges)
        .switchMap(() => this.getSortedData());
    });

  }
  disconnect() { }

  compare(a: string, b: string, isAsc: boolean) {
      return (a < b ? -1 : 1) * (isAsc ? 1 : -1);
  }

  /** Returns a sorted copy of the database data. */
  getSortedData(): Observable<Role[]> {

    return this.roles.map(data => {
      if (!this._sort.active || this._sort.direction == '') { return data; }

      return data.sort((a, b) => {
        let isAsc = this._sort.direction == 'asc';
        switch (this._sort.active) {
          case 'roleAvatar': return this.compare(a.name[0], b.name[0], isAsc);
          case 'roleName': return this.compare(a.name, b.name, isAsc);
        }
      });

    });
  }
}