Angular 5 sort by date

Issue

I have a table of lessons and I would like to order them by date. Since Angular 5 doesn’t have the orderBy pipe and all the solutions I have found so far can only be applied to numbers and strings I would be grateful if someone could help me with this. This is the body of my table

<tbody>
  <tr *ngFor="let lesson of lessons">
    <th scope="row">{{lesson.date | date:'dd.MM.yyyy H:mm'}}</th>
    <td>{{lesson.address.locationName}}</td>
    <td>{{lesson.topic}}</td>
    <td>{{lesson.homework}}</td>     
  </tr>
</tbody>

and this is a fragment of my component.ts file

public lessons = [];

ngOnInit() {
this.localStorage.getItem<number>('selectedProfileId').subscribe((id) => {
     this._profileService.showLessons(id)
     .subscribe(data => this.lessons = data,
     );
   });     
 } 

Solution

Sort lessons using Array.prototype.sort() in your component class prior to subscribing/binding lessons. Here is how you can sort lessons coming in from your service prior to binding using RxJS operator map() in descending order. map() is really powerful in terms of transforming data streams prior to subscribe().

this._profileService.showLessons(id)
    .pipe(
        map(lessons => lessons.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime()))
    )
    .subscribe(lessons => this.lessons = lessons);

Depending on your TsLint settings/configuration, you may need to utilize getTime() to appease the compiler:

lessons.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime())

Here is a StackBlitz showing the basic functionality in action.

Note*pipe() is using with RxJS 5.5+. If you are using an older version of RxJS, you can simply just import map() directly and using it as follows:

this._profileService.showLessons(id)
    .map(lessons => lessons.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime()))
    .subscribe(lessons => this.lessons = lessons);

Answered By – Alexander Staroselsky

Answer Checked By – Willingham (AngularFixing Volunteer)

Leave a Reply

Your email address will not be published.